美文网首页程序员
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