最近在学习webpack,边学边练习,下面是对一些应用到的属性、插件记录分享出来,也方便以后查找与复习,过程中碰到了一些坑,在注释中有说明:

const path = require('path')
const webpack = require("webpack")

const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

function parseUrl(dir) {
    let mark = '\\'.indexOf(dir) !== -1 ? '\\' : '\/';
    return dir.split(mark).slice(0, -1).join(mark);
}
/**
 * 说明
 * 
 * 1、可以通过import(\/* webpackChunkName: "lodash_file" *\/ 'lodash').then()这种方式动态添加Chunk,
 *      打包以后会独立成一个文件,注释部分结合output- chunkFilename 命名打包后的文件名
 * 2、chunk名称,可以通过entry进行定义,也有一些默认的chunk包
 */
module.exports = {
    entry: {  // 命名chunk,后面可以通过属性名调用到
        app: './app/index.js',
        check: './src/check.js',
        repeat: './src/repeat.js',
        vender: [
            'colors',
            'lodash'
        ]
    },
    
};

output

output: {
    // 文件用hash打包的时候([name].[chunkhash].js),需要关闭热替换,生产环境是不需要热替换的
    // filename: '[name].bundle.js',
    filename: '[name].[chunkhash].js',
    path: path.resolve(parseUrl(__dirname), 'dist'),
    publicPath: '/',  // webpack-dev-middleware插件用到的公共路径,在server.js文件中会用到
    chunkFilename: '[name].bundle.js',  // 可以控制动态加载文件名称
},
    

devtool

/**
 * devtool 
 * 
 * 追踪错误和警告,打包以后,使用打包文件也可以追踪到哪个文件出错,可以有多个选项,
 * 参见:https://segmentfault.com/a/1190000004280859 或 https://doc.webpack-china.org/configuration/devtool (官网)
 * 
 * 开发环境推荐使用 cheap-module-eval-source-map
 * 理由:
 * 1、不生成列信息,可以大幅提高 souremap 生成的效率,如果需要列信息,有些浏览器也可以自动生成列信息
 * 2、使用 eval 方式可大幅提高持续构建效率,参见 https://doc.webpack-china.org/configuration/devtool 效率对照表
 * 
 * 生产环境使用 source-map
 */
devtool: 'cheap-module-eval-source-map',
    

watch

// 监听项目是否有改动,如果有改动直接影响修改
watch: true,
watchOptions: {
    // 重新构建一次的延迟时间,在这段时间内有其他变动,会收集起来一起构建
    aggregateTimeout: 300,
    poll: 1000,  // 每秒检查一次变动
    ignored: /node_modules/  // 忽略node_modules文件夹中的文件变动,提升性能
},

devserver

//  构建一个web服务器
devServer: {
    contentBase: '../dist',  // 指定服务响应目录
    hot: true,  // 启用热替换模块 需要在入口文件中进行配置监听,详细参考文档https://doc.webpack-china.org/guides/hot-module-replacement/
},

module

module: {
    // 解析文件时匹配相对应的loader
    rules: [
        {
            test: /\.css$/,
            use: ["style-loader", "css-loader"],
            use: ExtractTextPlugin.extract({  // 样式独立打包
                use: 'css-loader'
            })
        },
        {
            test: /\.(png|svg|jpg|gif)$/,
            use: [
                'file-loader'
            ]
        }
    ]
},

plugins

plugins: [
    // 分离css依赖,生成独立样式包,放入参数文件中(没有会自动生成)
    new ExtractTextPlugin('styles.css'),

    // 生成html模板,调用了webpack生成的所有包
    new HtmlWebpackPlugin({
        title: 'Output Management',
        filename: 'index.html',
        // chunksSortMode: 'none',  // 模块排列顺序
        // chunks: ['app'],  // 渲染模板,输入入口定义的模板名称
        excludeChunks: ['check'], // 排除的渲染模板,以输入入口定义的模板名称为准
        template: 'index.html'  // 模板路径,在现有模板的基础上将打包生成的chucks添加上去
    }),

    // 先清除文件夹后生成,避免不必要的文件存在,根目录下的不能清除
    new CleanWebpackPlugin(['../dist']),

    // prints more readable module names in the browser console on HMR updates
    new webpack.NamedModulesPlugin(),

    /**
     * 热替换
     * 
     * 需要在devServer属性配置 hot:true 并且创建组件 启动热替换
     * 通过 module.hot 属性,用来接收监听接口 放到入口文件中
     * 使用热替换可以实现局部刷新,节省开发时间
     * 如果没有引入热替换,修改后就会全部刷新,影响响应速度
     * HMR 修改样式表时,需要在hot下引入接口,
     * 注意:使用热替换监听样式修改时,不能启动样式表独立打包模式,如果启动浏览器就不能响应到样式的修改
     * API链接:https://doc.webpack-china.org/api/hot-module-replacement
     */
    new webpack.HotModuleReplacementPlugin(),

    // 代码压缩,可以配置source map模式
    // new UglifyJSPlugin({
    //     // 使用source map模式(devtool属性必须设置为devtool: 'source-map')
    //     // 作用:在生产环境中也可以很方便的调试代码,类似于devtool: 'inline-source-map'模式
    //     sourceMap: true
    // }),

    new webpack.DefinePlugin({
        // 定义环境变量,可以在打包入口文件中获取到,相应环境变量
        'process.env': {
            'NODE_ENV': JSON.stringify('production')
        }
    }),

    // 将公共的依赖模块提取到已有的入口 chunk 中 
    // 可以创建多个
    // 可以提取自带 chunk 独立打包,比如:boilerplate 、 manifest ....
    new webpack.optimize.CommonsChunkPlugin({
        name: 'common', // chunk 的名称
        filename: 'common_file.js',  // 输出 chunk 文件名

        /**
         * 公共 chunk 之前所需要包含的最少数量的 chunks(也就是有几个chunk依赖)
         * 
         * 1、可选择 number|Infinity(马上生成 公共chunk,但里面没有模块)|function(module, count) -> boolean,
         * 2、可以调用函数 返回true的文件打包成独立文件,false 不会独立成包
         * 
         * @param module 模块信息
         * @param count 调用数量
         */
        minChunks: function (module, count) {
            // 禁止打包样式相关文件(有组件针对样式文件打包)
            if (module.resource && (/^.*\.(css|scss)$/).test(module.resource)) {
                return false;
            }
            // node_modules文件夹中的文件独立打包
            return module.context && module.context.indexOf("node_modules") !== -1;
        }
    }),

    // 可以根据 entry 或name名称进行分离打包,
    // 如果和 chunk = 'common' 共用,会报错
    new webpack.optimize.CommonsChunkPlugin({
        name: "vender",
        minChunks: Infinity
    }),

    // 避免hash发生变化
    // new webpack.HashedModuleIdsPlugin(),
]

如果有什么不对的地方,欢迎指正。


listenWind
271 声望3 粉丝