前端大宝剑React.js

02-Webpack4配置增强

2019-06-20  本文已影响15人  七玄之主

我们已经完成了基于React的脚手架工程的创建,现在让我们来进一步增强我们的工程,已方便日后的开发。

增强Webpack

清理 /dist 文件夹

dist文件夹里包含了我们生成的各种打包文件,我们更新生成配置后,如果不即使删除里面的残留文件,可能导致旧打包文件和新打包文件共存的情况。

我们可以在编译时添加脚本删除,如下所示:

"build": "rd /S /Q dist && webpack"

也可以通过Webpackclean-webpack-plugin插件来实现。

安装插件yarn add -D clean-webpack-plugin

修改webpack.config.js文件,加入html-webpack-plugin插件

    // 管理插件,通过插件实现增强功能
    plugins: [
        // 每次编译前清除dist文件夹
        new CleanWebpackPlugin(),
    ],

区分开发和生成环境

开发环境(development)和生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server。而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。
基于以上原理,我们将原有的webpack.config.js一个配置文件分割为webpack.common.jswebpack.dev.jswebpack.prod.js三个配置文件。

首先安装yarn add -D webpack-merge

根据原有webpack.config.js文件将对应配置分散到三个配置文件中

webpack.common.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack')

module.exports = {
    // 入口文件
    entry: './src/index.tsx',
    // 需要解析的文件后缀名
    resolve: {
        extensions: ['.tsx', '.ts', '.js']
    },
    // 管理插件,通过插件实现增强功能
    plugins: [
        // 自动清理dist
        new CleanWebpackPlugin(),
        // 根据模板生成html
        new HtmlWebpackPlugin({
            title: 'My App',
            template: './src/index.html'
        }),
    ],
    // 配置项目处理的不同文件及模块
    module: {
        rules: [
            {
                test: /\.(ts|tsx)?$/,
                loader: 'awesome-typescript-loader'
            },
        ]
    }
};

webpack.dev.js

const merge = require('webpack-merge')
const common = require('./webpack.common.js')
const webpack = require('webpack')
const path = require('path');

module.exports = merge(common, {
    // 标识配置为开发用
    mode: 'development',
    // 控制是否生成,以及如何生成 source map
    devtool: 'cheap-module-eval-source-map',
    // 管理开发服务器
    devServer: {
        // 查找文件路径
        contentBase: 'dist',
        // 启用 HMR
        hot: true,
    },
    plugins: [
        // 当开启 HMR 的时候使用该插件会显示模块的相对路径,建议用于开发环境
        new webpack.NamedModulesPlugin(),
        // 启用 HMR 热更新,建议用于开发环境
        new webpack.HotModuleReplacementPlugin()
    ],
    // 管理输出
    output: {
        // 定义输出文件名规则
        filename: '[name].bundle.js',
        // 定义输出文件名路径
        path: path.resolve(__dirname, 'dist'),
    },
})

webpack.prod.js

const merge = require('webpack-merge')
const common = require('./webpack.common.js')
const webpack = require('webpack')
const path = require('path');

module.exports = merge(common, {
    // 标识配置为生产用
    mode: 'production',
    // 控制是否生成,以及如何生成 source map
    devtool: 'source-map',
    // 管理输出
    output: {
        // 定义输出文件名规则
        filename: '[name].[contenthash].js',
        // 定义输出文件名路径
        path: path.resolve(__dirname, 'dist'),
    },
})

最后修改package.json

"scripts": {
    "build": "webpack --config webpack.prod.js",
    "dev": "webpack-dev-server --config webpack.dev.js"
  },

Source Map说明

Webpack的打包过程中,会对源代码进行压缩,合并,编译等操作,导致编译后的代码和源码差异较大。为了更容易地追踪错误和警告,通过JavaScript 提供的source map功能,能够将编译后的代码映射到源代码上,便于错误定位。

Webpack中,是通过devtool配置项来指定构造的source map类型。配置项很多,但大致可以划分为5类,其余配置项可以是其任意组合。

综上所示,我们在开发环境选用cheap-module-eval-source-map,就能够定位到各个原始文件上。生产环境则考虑使用source-map

代码压缩

Webpack4的mode是production时,会自动开启js的压缩,不过这里我们还是使用uglifyjs-webpack-plugin插件。

安装

yarn add -D uglifyjs-webpack-plugin

修改webpack.prod.js文件

module.exports = merge(common, {
    // 标识配置为生产用
    mode: 'production',
    // 控制是否生成,以及如何生成 source map
    devtool: 'source-map',
    plugins: [
        new UglifyJSPlugin({
            sourceMap: true
        }),
    ],
    // 管理输出
    output: {
        // 定义输出文件名规则
        filename: '[name].[contenthash].js',
        // 定义输出文件名路径
        path: path.resolve(__dirname, 'dist'),
    },
})

这里需要注意一点,UglifyJSPlugin压缩插件不能解析es6语法,需要引入bable来处理es6,es7的js文件的编译。

指定环境

程序中使用的某些第三方library可能会和process.env.NODE_ENV环境变量关联,比如在生产环境中增加额外的日志记录或测试,在生产环境中增加一些优化。因此我们根据不同的环境预设好process.env.NODE_ENV的值。NODE_ENV本质上是Node.js露给执行脚本的系统环境变量,同时并不能在Webpack.prod.js类似的构建脚本中预设NODE_ENV的值,但我们可以通过webpack内置的 DefinePlugin为所有的依赖定义这个变量。

对应环境的webpack配置文件中增加如下所示的插件配置:

// 预设程序执行环境
new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
})
上一篇下一篇

猜你喜欢

热点阅读