React编译环境配置:webpack3迁移至webpack4

这次我们以inputPassword组件为例,将编译配置环境 从webpack3迁移至webpack4,新装的webpack版本是4.14,但是配置文件还是用的webpack3的配置。

git地址:https://github.com/jean0218/react-inputPassword

先来看看pack.json文件:

{
  "name": "react-inputpassword",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "webpack": "webpack --config ./build/webpack.config.js",
    "start": "webpack-dev-server --config ./build/webpack.config.js",
    "dev": "webpack --config ./build/webpack.dev.config.js",
    "build": "webpack --progress --profile --colors --config ./build/webpack.pro.config.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/jean0218/react-inputPassword.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/jean0218/react-inputPassword/issues"
  },
  "homepage": "https://github.com/jean0218/react-inputPassword#readme",
  "dependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.7.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "css-loader": "^0.28.11",
    "enzyme-adapter-inferno": "^1.3.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.2.0",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-test-renderer": "^16.4.1",
    "style-loader": "^0.21.0",
    "webpack": "^4.14.0",
    "webpack-dev-server": "^3.1.4",
    "webpack-merge": "^4.1.3"
  },
  "devDependencies": {
    "babel-jest": "^23.2.0",
    "enzyme": "^3.3.0",
    "enzyme-adapter-react-16": "^1.1.1",
    "jest": "^23.3.0"
  }
}

找到webpack配置文件,放在build目录下,原有webpack文件配置如下:

webpack.base.config.js(webpack基础配置)

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const fileEntry = require('./fileEntry.js');

const webpackBaseConfig = {
    resolve: {
        extensions: [".js", ".json", ".jsx"],
        alias: {
            images: path.resolve(__dirname, '../examples/static/images'),
        }
    },

    entry: {
        examples:path.resolve(__dirname, '../examples/index.js'),
        demo01:path.resolve(__dirname, '../examples/demo01.js')
    },
    
    module: {
        noParse: /node_modules\/(jquey\.js)/,
        rules: [{
            test: /\.(js|jsx)$/,
            use: [{
                loader: 'babel-loader',
                options: {
                    "presets": [
                        "es2015", 'stage-0', 'react'
                    ]
                }
            }]       
        },{
            test: /\.(png|jpg|gif)$/,
            use: [{
                loader: 'file-loader',
                options: {
                    limit: 25000,
                    name: 'images/[name][hash:6].[ext]',
                    // 我们选择加载的图片格式为png,jpg,jpeg,gif,并限定当文件小于25kb,转换为base64编码。
                    // 优势:将一些小并且不常更新的图片转换base64编码后,可以减少一次或多次http请求。
                    // 但这个limit应该定义成一个合适的值,因为如果将稍大些的图片转为base64后,会生成大量字符,
                    // 反而降低我们的加载速度。
                }
            }]
        },{
            test: /\.(woff|woff2|eot|ttf|svg|otf)$/,
            loader: 'file-loader',
            options: {
                name: 'fonts/[name].[ext]'
            }
        }]
    },

    plugins: [
        new webpack.optimize.ModuleConcatenationPlugin(),
    ],
}

fileEntry.map(function(item) {//新文件输出 
    webpackBaseConfig.entry[item.fileName] =  path.resolve(__dirname, item.sourceFile);
    const chunksSort = item.chunks
    const htmlPackage = new HtmlWebpackPlugin({
        //favicon: 'path/to/yourfile.ico',//给生成的 html 文件生成一个 favicon
        title: item.title, //生成的html文档的标题
        template: path.resolve(__dirname, item.template),
        filename: item.targetFile, //输出文件的文件名称,默认为index.html,可以配置输出文件指定目录位置,例如'html/index.html'
        //filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
        //指定生成的html文件内容中的link和script路径是相对于生成目录下的,写路径的时候请写生成目录下的相对路径。
        //hash: false,//true|false,是否为所有注入的静态资源添加webpack每次编译产生的唯一hash值
        showErrors: true, //是否将错误信息输出到html页面中,便于调试
        //inject: 'body', //所有JavaScript资源插入到body元素的底部
        chunks: item.chunks,
        //允许插入到模板中的一些chunk,不配置此项默认会将entry中所有的thunk注入到模板中。
        //在配置多个页面时,每个页面注入的thunk应该是不相同的,需要通过该配置为不同页面注入不同的thunk;
        //excludeChunks: ,//这个与chunks配置项正好相反,用来配置不允许注入的thunk。
        chunksSortMode: (argument, argument2) =>{
            //none | auto| function,默认auto; 允许指定的thunk在插入到html文档前进行排序。
            //function值可以指定具体排序规则;auto基于thunk的id进行排序; none就是不排序
            var aIndex = chunksSort.indexOf(argument.names[0]);
            var bIndex = chunksSort.indexOf(argument2.names[0]);
            aIndex = aIndex < 0 ? chunksSort.length + 1 : aIndex;
            bIndex = bIndex < 0 ? chunksSort.length + 1 : bIndex;
            return aIndex - bIndex;
        } 
    });           
    webpackBaseConfig.plugins.push(htmlPackage);
});

module.exports = webpackBaseConfig;

其中的fileEntry.js文件主要用于生成html文件,这里就不再贴出来了。

webpack.config.js(本地运行环境配置)

const webpack = require('webpack');
const path = require('path');
const webpackBaseConfig = require('./wepback.base.config.js');
const merge = require('webpack-merge');
const outputDir = 'dist';



const webpackConfig = merge(webpackBaseConfig, {
    devtool: 'cheap-module-eval-source-map',
    output: {
        path: path.resolve(__dirname, '../' + outputDir + '/'),
        filename: 'js/[name].js',
        chunkFilename: 'js/[name].chunks.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/, 
                use:[
                    'style-loader',
                    'css-loader'
                ]
            }
        ],
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
    ],
});


module.exports = webpackConfig;

我们来看看webpack4相对于3新增了哪些内容:

1、不止需要安装webpack,还需要安装webpack-cli

在webpack3中,webpack本身和它的cli以前都在同一个包中,但在第4版中,它们两者已经分开,所以我们的webpack需要安装两个包,全局安装webpack

 npm install webpack -g

再全局安装webpack-cli

npm install webpack-cli -g

安装完成后出现版本提示,就说明该包已经安装成功。

(这个安装是在配置react-loadList组件时截图的,除了项目不同其它都是一样的)

2、新增了mode参数来表示生产还是开发

按照以上配置,我们运行 npm run start,文件能正常编译,但会看到如下警告:

这个警告告诉我们,'mode'选项没有被设置,必须设置'mode'选项。webpack4新增了mode参数来表示生产还是开发,新增的参数有两个可选值:development和production。不可缺省,缺省就会像上图一样报警告,其中

production 模式:

  • 默认提供所有可能的优化,如代码压缩/作用域提升等

  • 不支持 watching

  • process.env.NODE_ENV 的值不需要再定义,默认是 production

development 模式:

  • 主要优化了增量构建速度和开发体验

  • process.env.NODE_ENV 的值不需要再定义,默认是 development

  • 开发模式下支持注释和提示,并且支持 eval 下的 source maps

可以在pack.json中配置

webpak --mode development

也可以配置文件中配置:

mode:'development',
devtool: 'cheap-module-eval-source-map',

如果原有的文件中有new webpack.DefinePlugin,加上mode选项后,则需要删除 

new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") })

再运行npm run start,这个时候警告已经没有了。

3、rules中需要增加type类型,指定模块类型

webpack 4之前,js 是 webpack 中的唯一模块类型,因而不能有效地打包其它类型的文件。而 webpack 4 则提供了 5 种模块类型:

  • javascript/auto: (webpack 3中的默认类型)支持所有的JS模块系统:CommonJS、AMD、ESM
  • javascript/esm: EcmaScript 模块,在其他的模块系统中不可用(默认 .mjs 文件)
    • 相较于javascript/auto模式更严格,导入的名称必须存在于导入的模块中
    • 动态的模块(非ESM, 如CommonJs)只能通过import导入,其它方式的导入都会报错
  • javascript/dynamic: 仅支持 CommonJS & AMD,EcmaScript 模块不可用
  • json: 可通过 require 和 import 导入的 JSON 格式的数据(默认为 .json 的文件)
  • webassembly/experimental: WebAssembly 模块(处于试验阶段,默认为 .wasm 的文件)

(我在看到这块时,产生了一个疑问,这些都是js的模型,图片、字体类的不需要增加type类型么?待以后有机会再补充)

5、CommonsChunkPlugin需要替换

     本次更新内容中没有这一项,暂时不编写,以后更新。

这样,我们的webpack3成功迁移至4了,相对于2迁移至3是不是简单了很多。

参考:

https://blog.csdn.net/qq_26733915/article/details/79446460

https://blog.csdn.net/VhWfR2u02Q/article/details/79366615

猜你喜欢

转载自blog.csdn.net/jean850218/article/details/81181720