Webpack系列-基本配置

349 阅读3分钟

webpack.config.js

const path = require('path');
module.exports = {
    mode: "production" // "production" | "development" | "none"
    // mode 告知webpack 使用相应环境的内置优化,
    
    entry: 'index.js',  // string | object | array
    entry: ["./app/entry1", "./app/entry2"],
    entry: {
        a: "./app/entry-a",
        b: ["./app/entry-b1", "./app/entry-b2"]
    },
    
    // webpack打包如何输入结果配置项
    output: {
        path: path.resolve(__dirname, "dist"), // string
        // 所有输出文件的目标路径
        // 必须是绝对路径(使用 Node.js 的 path 模块)
        filename: "bundle.js", // string
        filename: "[name].js", // 用于多个入口点(entry point)名字使用入口配置的名字
        filename: "[chunkhash].js", // 用于长效缓存
        // 「入口分块(entry chunk)」的文件名模板
        
        publicPath: "/assets/", // string
        publicPath: "",
        publicPath: "https://cdn.example.com/",
        // 输出解析文件的目录,url 相对于 HTML 页面
        
        // 下边多用于打组件和基础库
        library: "MyLibrary", // string,
        // 导出库(exported library)的名称
        
        // 导出库(exported library)的类型
        libraryTarget: "var", // 默认值 变量定义于根作用域下
        libraryTarget: "umd", // 通用模块定义
        libraryTarget: "umd2", // 通用模块定义
        libraryTarget: "commonjs2", // exported with module.exports
        libraryTarget: "commonjs", // 作为 exports 的属性导出
        libraryTarget: "amd", // 使用 AMD 定义方法来定义
        libraryTarget: "this", // 在 this 上设置属性
        libraryTarget: "assign", // 盲分配(blind assignment)
        libraryTarget: "window", // 在 window 对象上设置属性
        libraryTarget: "global", // property set to global object
        libraryTarget: "jsonp", // jsonp wrapper
        
        pathinfo: true, // boolean
        // 在生成代码时,引入相关的模块、导出、请求等有帮助的路径信息。
        chunkFilename: "[id].js",
        chunkFilename: "[chunkhash].js", // 长效缓存(/guides/caching)
        // 「附加分块(additional chunk)」的文件名模板
        sourceMapFilename: "[file].map", // string
        sourceMapFilename: "sourcemaps/[file].map", // string
        // 「source map 位置」的文件名模板
        jsonpFunction: "myWebpackJsonp", // string
        // 用于加载分块的 JSONP 函数名
    }
    modules: {
        // 关于模块配置
        rules: [
        // 模块规则(配置 loader、解析器等选项)
            {
                test: /\.jsx?$/,
                include: [
                  path.resolve(__dirname, "app")
                ],
                exclude: [
                  path.resolve(__dirname, "app/demo-files")
                ],
                // 这里是匹配条件,每个选项都接收一个正则表达式或字符串
                // test 和 include 具有相同的作用,都是必须匹配选项
                // exclude 是必不匹配选项(优先于 test 和 include)
                // 最佳实践:
                // - 只在 test 和 文件名匹配 中使用正则表达式
                // - 在 include 和 exclude 中使用绝对路径数组
                // - 尽量避免 exclude,更倾向于使用 include
                loader: "babel-loader",
                // 应该应用的 loader,它相对上下文解析
                options: {
                    presets: ["es2015"]
                },
                // loader 的可选项
            },
            {
            test: /\.html$/,
                use: [
                    // 应用多个 loader 和选项
                    "htmllint-loader",
                    {
                        loader: "html-loader",
                        options: {
                        /* ... */
                        }
                    }
                ]
            },
            { oneOf: [ /* rules */ ] },
            // 只使用这些嵌套规则之一
            { rules: [ /* rules */ ] },
            // 使用所有这些嵌套规则(合并可用条件)
            { resource: { and: [ /* 条件 */ ] } },
            // 仅当所有条件都匹配时才匹配
            { resource: { or: [ /* 条件 */ ] } },
            { resource: [ /* 条件 */ ] },
            // 任意条件匹配时匹配(默认为数组)
            { resource: { not: /* 条件 */ } }
            // 条件不匹配时匹配
        ]
    },
    
    resolve: {
        // 解析模块请求的选项
        modules: [
            "node_modules",
            path.resolve(__dirname, "app")
        ],
        // 告诉 webpack 解析模块时应该搜索的目录
        // 绝对路径和相对路径都能使用
        extensions: [".js", ".json", ".jsx", ".css"],
        // 使用的扩展名 import文件是可省略的扩展名
        alias: {
            // 模块别名列表
            "module": "new-module",
            // 起别名:"module" -> "new-module" 和 "module/path/file" -> "new-module/path/file"
            "only-module$": "new-module",
            // 起别名 "only-module" -> "new-module",但不匹配 "only-module/path/file" -> "new-module/path/file"
            "module": path.resolve(__dirname, "app/third/module.js"),
            // 起别名 "module" -> "./app/third/module.js" 和 "module/file" 会导致错误
            // 模块别名相对于当前上下文导入
        },
    },
    
    performance: {
        // 设置如何通知「资源(asset)和入口起点超过指定文件限制」
        hints: "warning", // 枚举
        hints: "error", // 性能提示中抛出错误
        hints: false, // 关闭性能提示
        maxAssetSize: 200000, // 整数类型(以字节为单位)
        maxEntrypointSize: 400000, // 整数类型(以字节为单位)
        assetFilter: function(assetFilename) {
            // 提供资源文件名的断言函数
            return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
        }
    },
    
    devtool: "source-map", // enum
    // 通过在浏览器调试工具(browser devtools)中添加元信息(meta info)增强调试
    // 牺牲了构建速度的 `source-map' 是最详细的。
    devtool: "inline-source-map", // 嵌入到源文件中
    devtool: "eval-source-map", // 将 SourceMap 嵌入到每个模块中
    devtool: "hidden-source-map", // SourceMap 不在源文件中引用
    devtool: "cheap-source-map", // 没有模块映射(module mappings)的 SourceMap 低级变体(cheap-variant)
    devtool: "cheap-module-source-map", // 有模块映射(module mappings)的 SourceMap 低级变体
    devtool: "eval", // 没有模块映射,而是命名模块。以牺牲细节达到最快。
    
    context: __dirname, // string(绝对路径!)
    // webpack 的主目录
    // entry 和 module.rules.loader 选项
    // 相对于此目录解析
    
    target: "web", // 浏览器 枚举
    // 告知 webpack 为目标(target)指定一个环境。
    // bundle 应该运行的环境
    target: "webworker", // WebWorker
    target: "node", // node.js 通过 require
    target: "async-node", // Node.js 通过 fs 和 vm
    target: "node-webkit", // nw.js
    target: "electron-main", // electron,主进程(main process)
    target: "electron-renderer", // electron,渲染进程(renderer process)
    target: (compiler) => { /* ... */ }, // 自定义
    
    externals: ["react", /^@angular\//],
    // 防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖
    externals: "react", // string(精确匹配)
    externals: /^[a-z\-]+($|\/)/, // 正则
    externals: { // 对象
        angular: "this angular", // this["angular"]
        react: { // UMD
            commonjs: "react",
            commonjs2: "react",
            amd: "react",
            root: "React"
        }
    },
    externals: (request) => { /* ... */ return "commonjs " + request }
    // 不要遵循/打包这些模块,而是在运行时从环境中请求他们
    // 例如从CDN引入jQuery,而不是把它打包
    
    stats: "errors-only",
    stats: { //object
        assets: true,
        colors: true,
        errors: true,
        errorDetails: true,
        hash: true,
        // ...
    },
    // 精确控制要显示的 bundle 信息
    
    devServer: {
        proxy: { // 设置代理 请求到 /api/users 现在会被代理到请求 http://localhost:3000/api/users
            '/api': 'http://localhost:3000'
        },
        '/api': {
            target: 'http://localhost:3000',
            pathRewrite: {'^/api' : ''}
        } 
        // 请求到 /api/users 现在会被代理到请求 http://localhost:3000/users
        contentBase: path.join(__dirname, 'public'), // 告诉服务器从哪个目录中提供内容。只有在你想要提供静态文件时才需要
        compress: true, // 一切服务都启用 gzip 压缩:
        historyApiFallback: true, // 当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html
        hot: true, // 启用 webpack 的 模块热替换 功能
        https: false, // true for self-signed, object for cert authority
        noInfo: true, // only errors & warns on hot reload
        // ...
    },
    plugins: [ // 插件
        // ...
    ],
}