5.webpack4配置详解

128 阅读1分钟

enter

/**
 *  entry: 入口七点
 *      1. string --> './src/index.js
 *         打包形成一个chunk,输出一个bundle文件
 *         此时chunk的名称默认是main
 * 
 *      2.array --> ['./src/index.js','./src/test.js'],
 *          多入口
 *          所有入口文件最终只会形成一个chunk(main),输出出去只有一个bundle文件,默认名称是main
 *           ---> 例子:HMR(热模块替换)功能中让html热更新生效~
 *      3.object
 *          多入口
 *          有几个入口文件就形成几个chunk,输出几个bundle文件
 *          此时chunk的名称是key
 * 
 *      --->  特殊用法(dll)
 *          {
 *              // 所有的入口文件都会形成一个chunk,输出出去只有一个bundle(index)文件
 *              index: ['./src/index.js','./src/test.js'],
 *              // 形成一个chunk,输出一个bundle文件
 *              add: './src/test.js'
 *         }
 */ 
 module.exports = {
    // string
    // entry: './src/index.js',
    
    // array
    // entry: [
    //     './src/index.js',
    //     './src/test.js'
    // ],

    // object
    entry: {
        index:  './src/index.js',
        test: './src/test.js'
    }
}

output

  output: {
        // 文件名称(指定名称+目录)
        filename: 'js/[name].js',
        path: resolve(__dirname, 'build'),
        // 所有资源引入公共路径前缀 --> 'imgs/a.jpg'(当前文件同级目录查找)
        //                        --> '/imgs/a.jpg'(根路径下查找)
        // publicPath: '/',
        
        // 非入口chunk的名称,比如通过import的chunk, opti..的chunk
        // 如果这个不声明 这会按上面的filename命名,默认chunk的name 是 0 1 2 3
        chunkFilename: '[name]_chunk.js',
        library: '[name]', // 整个库向外暴露的变量名,用var定义
        // libraryTarget: 'window' // 变量名添加到那个上 browser
        // libraryTarget: 'global' // 变量名添加到那个上 node
        libraryTarget: 'commonjs' // 通过commonjs暴露出去 exports["main"] = ...(详情看main.js)
    }

module

 module: {
        rules: [
            // loader的配置
            {
                test: /\.css$/,
                // 多个loader用use
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.js$/,
                // 排除node_modules下的js文件
                exclude: /node_modules/,
                // 只检查src下的js文件
                include: resolve(__dirname, 'src'),
                // 优先执行
                enforce: 'pre',
                // 延后执行
                // enforce: 'post',
                // 单个loader用loader
                loader: 'eslint-loader'
            },
            {
                // 以下配置只会生效一个
                oneOf: [

                ]
            }
        ]
    }

resolve

// 解析模块的规则
    resolve: {
        // 配置解析模块路径别名:优点简写路径  缺点路径没有提示
        alias: {
            $css: resolve(__dirname, 'src/css')
        },
        // 配置省略文件路径的后缀名,从左到右依次匹配 
        extensions: ['.js', '.json', '.css'],
        // 
        modules: [
            resolve(__dirname, '../../../node_modules'), // 直接告诉node_modules的位置,减少查找时间,提高打包速度
            'node_module' // 如果上面的没找到,则从本目录依次往上查找node_modules
        ]
    }

devServe

 devServer: {
        // 运行代码的目录
        contentBase: resolve(__dirname, 'build'),
        // 监视contentBase 目录下的所有文件, 一旦文件变化就会reload
        watchContentBase: true,
        watchOptions: {
            // 忽略监视文件
            ignored: /node_modules/
        },
        // 开启gzip压缩
        compress: true,
        // 端口号
        port: 5000,
        // 域名
        host: 'localhost',
        // 自动打开浏览器
        open: true,
        // 开启HRM功能
        hot: true,
        // 不要显示启动服务器日志信息
        clientLogLevel: 'none',
        // 除了一些基本启动信息以外,其他内容都不要显示
        quiet: true,
        // 如果出错了,不要全屏提示
        overlay: false,
        // 服务器代理 --> 解决开发环境下的跨域问题
        // 服务器跟服务器之间请求是没有跨域问题的
        // 测试发现谷歌浏览器没办法看出是真正去请求替代后的地址
        // proxy: {
        //     // 一旦devServer(5000)服务器接收到/api/xxx 的请求,就会把请求转发到另一个服务器(3000)
        //     '/api': {
        //         target: 'http://localhost:3000',
        //         // 在终端可以看真实请求地址
        //         logLevel: 'debug',
        //         // 发送请求时,请求路径重写: 将/api/xxx ---> /xxx(去掉/api)
        //         pathRewrite: {
        //             '^/api': ''
        //         }
        //     }
        // }
        // 测试
        proxy: {
            '/csdn': {
                target: 'https://blog.csdn.net',
                changeOrigin: true,
                logLevel: 'debug',
                pathRewrite: {
                    '^/csdn': ''
                }
            }
        }
    }

optimization

    optimization: {
        splitChunks: {
            chunk: 'all'
        }
    },
    // question: a.js 引用了 b.js(用contenthash命名), a中会记录b的contenthash文件名,如果b改了,那a也得改变,就失去了使用import动态语法切割代码的意义
    runtimeChunk: {
        name: entrypoint => `runtime-${entrypoint.name}`
    }