美文网首页程序员
create-react-app

create-react-app

作者: 在宇宙Debugger | 来源:发表于2017-12-01 15:37 被阅读478次

    create-react-app

    环境

    1. 创建react webpack环境
    • ts版本 create-react-app keshihua --scripts-version=react-scripts-ts
    • jsx版本 create-react-app keshihua
    1. 暴露配置项
    • npm run eject
    1. 增加对less的支持
    • npm install less-loader less --save-dev
    1. 修改 webpack.config.dev.jswebpack.config-prod.js 配置文件
    • /\.css$/ 改为 /\.(css|less)$/
    • 关键字 exclude 增加或修改 /\.(css|less)$/
    • 在修改 /\.(css|less)$/ 的代码中, use数组中加入 {loader: require.resolve('less-loader')}

    主要修改文件

    • config/webpack.config.dev.js
    • config/webpack.config.prod.js
    • config/paths.js
    1. 设置paths
      config/paths.js抛出的参数中需要设置以下2个参数
    • appBuild: 编译的目录
    • appSrc: 源文件的目录
    1. 设置module.exports.output
    • filename 作为js的目标文件夹,publicPath是编译根目录
      如: publicPath设置为/bulid/, filename设置为js/[name].js, 则最后生成的js位置是 /build/js/[name].js

    • entry 作为需要编译的js文件, 这里的路径是相对于项目根目录的, 最好写绝对路径

    • HtmlWebpackPlugin 用来编译html, template属性作为需要编译的html, 路径相对于项目根目录, 最好写绝对路径

    • cssFilename 属性作为编译css的目录

    • oneOf中寻找代码static/media/[name].[hash:8].[ext], 这个是资源路径

    1. 代码书写风格
      使用create-react-app 编译后的代码支持ES6, less, npm包管理
      引入一个文件通常使用import引入, 如
      import React, { Component } from 'react';
      // or
      import * as React from 'react';
      // or
      import 'antd/lib/affix/style';
    

    less也可以通过import引入, 如

      import './mobileBox.less';
    

    抛出一个方法使用 export

      export default MobileBox;
      // or
      export {MobileBox};
    
    1. JSX语法
      使用react支持JSX语法, 可以直接使用<div></div>的形式传值

    2. 一个文本闪烁的 demo

     import React, {Component} from 'react';
     import ReactDOM from 'react-dom';
     class A extends Component {
         constructor() {
             super();
             this.state = {
                 display: 'block'
             }
         }
    
         componentDidMount() {
             setInterval(() => {
                 this.setState({
                     display: this.state.display === 'block' ? 'none': 'block'
                 });
             }, 1000);
         }
    
         render () {
             return <div style={{
                 display: this.state.display
             }}>hello world</div>
         }
     }
    
     ReactDOM.render(<A />, document.body);
    
    1. 如何使用create-react-app 来编译多页面项目
      6.1. 全局搜索checkRequiredFiles, 清除对 appBuild, appSrc 的检查(找到以下代码并删除或注释)
        if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
          process.exit(1);
        }
      

    6.2 增加node代码如下:

      let HtmlWebpackPlugins = [];
      let entry = {};
      let htmlIndexArr = [];
    
      /**
      * readdirsSync 深度寻找一个路径下的所有文件
      * @param pathName  路径
      * @param callback  回调函数
      * 
      * 其他参数不用管, 回调使用
      * 回调中存在可以使用 srcFileName, fileName, middlePath
      * srcFileName: 文件路径
      * fileName:    文件名
      * middlePath:  相对pathName路径
      *          如传入的pathName为 a/, 实际路径为 a/b/c.js 则middlePath的值为b/c.js
      * 
      * 使用call, apply 调用的时候, 可以为this传入一个数字, 作为最大递归层数
      */
      function readdirsSync(pathName, callback, middle = pathName, z = 0) {
        let numberThis = Number(this);
        if (numberThis && z >= numberThis) return;
    
        fs.readdirSync(pathName).forEach((fileName) => {
          let srcFileName = path.join(pathName, fileName);
          let stat = fs.statSync(srcFileName);
          if (stat && stat.isFile()) {
            let middlePath = pathName.replace(middle, '');
            callback({ srcFileName, fileName, middlePath });
          } else if (stat && stat.isDirectory()) {
            readdirsSync.call(this, srcFileName, callback, pathName, z + 1);
          }
        });
      }
    
      /**
      * getChunks  获取一个文件的标识, 每个文件的标识是唯一的
      * @param pathName 
      * @param middle 
      */
      function getChunks(pathName, middle) {
        let str = path.join(middle, pathName.split('.').slice(0, -1).join('.')).replace(/\\/g, '/');
        str.startsWith('/') && (str = str.replace('/', ''));
        return str;
      }
    
      // 主页面名必须是index
      readdirsSync.call(2, paths.appSrc, function ({ srcFileName, fileName, middlePath }) {
          // 判断文件是否是js文件
        if (/^index.(js|jsx|ts|tsx)$/.test(fileName)) {
    
          // 获取文件唯一标识
          let chunkName = getChunks(fileName, middlePath);
    
          // 去除路径中的/
          let seps = middlePath.replace(path.sep, '');
    
          // 如果路径的目录是public,shared,images,data则跳过, 这些路径是预设的非组件的路径
          if (['public', 'shared', 'images', 'data'].indexOf(seps) !== -1) return;
    
          // 设置编译文件
          entry[chunkName] = [srcFileName];
    
          // 获取html模板文件路径
          let templateUrl = srcFileName.split('.').slice(0, -1).join('.') + '.html';
          
          // 是否存在这个模板, 如果不存在的话会用默认的模板代替
          let tempStat = fs.existsSync(templateUrl);
    
          // 设置html编译
          var htmlWebpackPlugin = new HtmlWebpackPlugin({
            inject: true,
            template: tempStat ? templateUrl : path.join(__dirname, 'webpack.html'),
            hash: true,
            minify: {
              removeComments: true,
              collapseWhitespace: true,
              removeRedundantAttributes: true,
              useShortDoctype: true,
              removeEmptyAttributes: true,
              removeStyleLinkTypeAttributes: true,
              keepClosingSlash: true,
              minifyJS: true,
              minifyCSS: true,
              minifyURLs: true,
            },
            chunks: [chunkName],
            filename: path.join(paths.appBuild, '/html/', middlePath + '.html')
          })
    
          htmlIndexArr.push(path.join('/build/html/', middlePath + '.html'));
          HtmlWebpackPlugins.push(htmlWebpackPlugin);
    
        }
      });
    

    相关文章

      网友评论

        本文标题:create-react-app

        本文链接:https://www.haomeiwen.com/subject/dfdwbxtx.html