Webpack 再入门(3)详细配置

496 阅读1分钟

详细配置

entry

entry 入口起点

  1. string

例:entry: 'src/index.js'

单入口,形成一个 chunk,输出一个 bundle

chunk 的名称默认为 main

  1. Array

多入口,多个文件只形成一个 chunk,输出一个 bundle

  1. object

例:entry: {index:'./src/index.js', main:'./src/main.js'}

多入口,有几个文件就是几个 chunk、输出几个 bundle

对象的 key 就是 chunk 的名称

嵌套用法 Recoed<string, string|string[]>

output

文件输出

output: {
    // 文件名称,指定名称+目录
    filename: 'js/[name].js',
    
    // 输出文件的公共目录
    path: path.resolve(__dirname, 'build'),
    
    // 资源引入的公共路径前缀,如 需要设置 CDN 前缀可需要
    publichPath: '/',

    // 非入口 chunk 的名称
    chunkFilename: `[name]_chunk.js`,
    
    // 整个库向外暴露的变量名
    library: `[name]`,
    
    // 变量添加到哪个对象上
    libraryTarget: `window`,
    // libraryTarget: `global`,
    // libraryTarget: `commonjs`,

module.rules


module: {
    rules: [
        {
            test: /\.js$/,
            // 引用单个 loader
            loader: 'eslint-loader',
        }, {
            test: /\.css$/,
            // 引用多个 loader
            use: ['style-loader','css-loader']
            // 排除目录
            exclude: /node_modules/,
            // 只检查某目录
            include: 'src',
            // 优先执行
            enforce: 'pre',
            // enforce: 'post', // 延后执行
            // loader 选项配置
            options: {
                ...
            },
            // 以下 loader 配置仅执行一个
            oneOf: [
                { test: /\.js$/, ...},
                ...
            ]
        } 
    ]
}


resolve

解析模块的规则

resolve: {
    // 模块的路径别名
    alias: {
        '~': path.resolve(__dirname, 'src')},
    },
    // 省略文件的后缀名
    extensions: ['.js', '.json'],
    // 解析模块是去哪个目录找
    modules: ['node_modules'],    
}

devServer

开发服务器配置

devServer: {
    // 运行代码的目录
    contentBase: resolve(__dirname, 'build'),
    // 见识 contentBase 目录下的所有文件,一旦文件变化,就会 reload
    watchContentBase: true,
    watchOptions: {
        // 忽略文件
        ignored: /node_modules/
    },
    // 启动 gzip 压缩
    compress: true,
    host: 'localhost',
    port: 3000,
    // 自动打开浏览器
    open: true,
    // 开启 HMR 功能
    hot: true,
    // 不要显示启动服务器的日志信息
    clientLogLevel: 'none',
    // 除了一些基本的启动信息以外,其他内容不要显示
    quiet: true,
    // 如果出错了,不要全屏提示
    overlay: false,
    // 服务器代理,解决开发环境跨域问题
    proxy: {
        '/api': {
            target: 'http://localhost: 3001',
            // 路径重写
            pathRewrite: {
                // 替换 /api/xxx --> /xxx
                '^/api': ''
            }
        }
    }
}

optimization

优化配置,主要影响生产模式打包

optimization: {
    splitChunks: {
        chunks: 'all',
        // 以下为默认值,可不写
        minSize: 30* 1024, // 分割的 chunk 最小为 30 KB
        maxSize: 0, // 最大没有限制
        minChunks: 1, // 要提取的 chunks 最少被引用 1 次
        maxAsyncRequests: 5, // 按需加载的时候并行加载的文件的最大数量
        maxInitialRequests: 3, // 入口 js 文件最大并行请求数量
        automaticNameDelimiter: '~', // 名称连接符
        name: true, // 可以使用命名规则
        cacheGroups: { // 分割 chunk 的组
            // node_modules 文件会被打包到 vendors 组的 chunk 中,--> vendors~xxx.js
            // 满足上面的公共规则,如大小超过 30KB,至少被引用过 1 次
            vendors: {  
                test: /[\\/]node_modules[\\/]/,
                // 优先级
                priority: -10,
            },
            default: {
                // 要提取的 chunk 最少被引用 2 次
                minChunks: 2,
                // 优先级
                priority: -20,
                // 如果当前要打包的模块,和之前已经提取的模块是同一个,就会复用,而不是重新打包模块
                reuseExistingChunk: true,
            }
        }
    },
    // 将当前模块的记录其他模块的 hash 单独打包一个文件 runtime
    // 解决:修改 a 文件导致 b 文件的 contenthash 变化,而导致缓存失效
    runtimeChunk: {
        name: entrypoint => `runtime-${entrypoint.name}`
    },
    // 配置生产环境的压缩方案:js 和 css
    // 默认使用了 terser 压缩代码
    minimizer: [
        new TerserWebpackPlugin({
            // 开启缓存
            cache: true,
            // 开启多进程打包
            parallel: true,
            // 启动 source-map
            sourceMap: true,
        }) 
    ]
}