《React+Redux前端开发实战》—1.1.6 Webpack配置详解

举报
华章计算机 发表于 2019/07/24 23:02:02 2019/07/24
【摘要】 本节书摘来自华章计算机《React+Redux前端开发实战》一书中的第1章,第1.1.6节,作者是徐顺发.

1.1.6  Webpack配置详解

  前面已经使用过webpack.config.js中的一些配置,本节将详细介绍Webpack的主要配置项。

  (1)模式mode:

  

  mode: "production",                                             // 生产模式

  mode: "development",                                          // 开发模式

  

  (2)入口entry:

  

  entry: "./app/entry",                                        // 入口可以是字符串、对象或数组

  entry: ["./app/entry1", "./app/entry2"],

  entry: {

      a: "./app/entry-a",

      b: ["./app/entry-b1", "./app/entry-b2"]

  },

  

(3)出口output:

  

  output: {                                                               // Webpack如何输出结果的相关选项

      path: path.resolve(__dirname, "dist"),        // 字符串

      // 所有输出文件的目标路径

      // 必须是绝对路径(使用Node.js的path模块)

      filename: "bundle.js",                                // 字符串

      filename: "[name].js",                               // 用于多个入口点(entry point)

      filename: "[chunkhash].js",                       // 用于长效缓存

      // 「入口分块(entry chunk)」的文件名模板

      publicPath: "/assets/",                              // 字符串   

      publicPath: "",

      publicPath: "https://cdn.example.com/",

      // 输出解析文件的目录,URL相当于HTML页面

      library: "MyLibrary", // string,

      // 导出库(exported library)的名称

      libraryTarget: "umd",                               // 通用模块定义

      libraryTarget: "commonjs2",                            // 作为exports的属性导出

      libraryTarget: "commonjs",                       // 作为exports的属性导出

      libraryTarget: "amd",                                // 使用amd定义方法来定义

      libraryTarget: "this",                                 // 在this上设置属性

      libraryTarget: "var",                                  // 变量定义于根作用域下

      libraryTarget: "assign",                             // 盲分配(blind assignment)

      libraryTarget: "window",                                  // 在window对象上设置属性

      libraryTarget: "global",                             // 设置global 对象

      libraryTarget: "jsonp",                                            // jsonp wrapper

      // 导出库(exported library)的类型

      /* 高级输出配置(点击显示) */    pathinfo: true,    // boolean

      // 以文件形式异步加载模块配置项

      chunkFilename: "[id].js",

      chunkFilename: "[chunkhash].js",              // 长效缓存(/guides/caching)

      // 「附加分块(additional chunk)」的文件名模板

      jsonpFunction: "myWebpackJsonp",                               // string

      // 用于加载分块的 JSONP 函数名

      sourceMapFilename: "[file].map",                           // string

      sourceMapFilename: "sourcemaps/[file].map",        // string

      // 「source map 位置」的文件名模板

      devtoolModuleFilenameTemplate: "webpack:///[resource-path]", // string

      // 「devtool 中模块」的文件名模板

      devtoolFallbackModuleFilenameTemplate: "webpack:///[resource-path]

        [hash]", // string

      // 「devtool 中模块」的文件名模板(用于冲突)

      umdNamedDefine: true, // boolean

      // 在 UMD 库中使用命名的 AMD 模块

      crossOriginLoading: "use-credentials",                   // 枚举

      crossOriginLoading: "anonymous",

      crossOriginLoading: false,

      // 指定运行时如何发出跨域请求问题

      /* 专家级输出配置(自行承担风险) */ 

  }

  

  (4)module模块处理:

  

   module: {

      // 关于模块配置

      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

          issuer: { test, include, exclude },

          // issuer 条件(导入源)

          enforce: "pre",

          enforce: "post",

          // 标识应用这些规则,即使规则覆盖(高级选项)

          loader: "babel-loader",

          // 应该应用的 loader,它相对上下文解析

          // 为了更清晰,-loader 后缀在Webpack 2中不再是可选的

          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: /* 条件 */ } }

        // 条件不匹配时匹配

      ],

  /* 高级模块配置(点击展示) */   

  noParse: [

        /special-library\.js$/

      ],

      // 不解析这里的模块

      unknownContextRequest: ".",

      unknownContextRecursive: true,

      unknownContextRegExp: /^\.\/.*$/,

      unknownContextCritical: true,

      exprContextRequest: ".",

      exprContextRegExp: /^\.\/.*$/,

      exprContextRecursive: true,

      exprContextCritical: true,

      wrappedContextRegExp: /.*/,

      wrappedContextRecursive: true,

      wrappedContextCritical: false,

      // specifies default behavior for dynamic requests

    },

  

  (5)resolve解析:

  

    resolve: {

      // 解析模块请求的选项(不适用于对 loader 解析)

      modules: [

        "node_modules",

        path.resolve(__dirname, "app")

      ],

      // 用于查找模块的目录

      extensions: [".js", ".json", ".jsx", ".css"],

      // 使用的扩展名

      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" 会导致错误

        // 模块别名相对于当前上下文导入

      },

      /* 可供选择的别名语法(点击展示) */   

   alias: [

        {

          name: "module",

          // 旧的请求

          alias: "new-module",

          // 新的请求

          onlyModule: true

          // 如果为true,那么只有module是别名

          // 如果为false,则"module/inner/path" 也是别名

        }

      ],

      /* 高级解析选项(点击展示) */    symlinks: true,

      // 遵循符号链接(symlinks)到新位置

      descriptionFiles: ["package.json"],

      // 从 package 描述中读取的文件

      mainFields: ["main"],

      // 从描述文件中读取的属性

      // 当请求文件夹时

      aliasFields: ["browser"],

      // 从描述文件中读取的属性

      // 以对此 package 的请求起别名

      enforceExtension: false,

      // 如果为 true,请求必不包括扩展名

      // 如果为 false,请求可以包括扩展名

      moduleExtensions: ["-module"],

      enforceModuleExtension: false,

      // 类似 extensions/enforceExtension,但是用模块名替换文件

      unsafeCache: true,

      unsafeCache: {},

      // 为解析的请求启用缓存

      // 这是不安全的,因为文件夹结构可能会改动

      // 但是性能改善是很大的

      cachePredicate: (path, request) => true,

      // predicate function which selects requests for caching

      plugins: [

        ...

      ]

      // 应用于解析器的附加插件

    },

  

  (6)performance打包后命令行如何展示性能提示,如果超过某个大小时是警告还是报错:

  

    performance: {

      hints: "warning",                 // 枚举 hints: "error", // 性能提示中抛出错误

      hints: false,                         // 关闭性能提示

      maxAssetSize: 200000,               // 整数类型(以字节为单位)

      maxEntrypointSize: 400000,       // 整数类型(以字节为单位)

      assetFilter: function(assetFilename) {

        // 提供资源文件名的断言函数

        return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');

      }

    },

  

  (7)devtool用于配置调试代码的方式,打包后的代码和原始代码存在较大的差异,此选项控制是否生成,以及如何生成sourcemap:

  

    devtool: "source-map",   // enum  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",                       // 没有模块映射,而是命名模块。以牺牲细节达到最快

    // 通过在浏览器调试工具(browser devtools)中添加元信息(meta info)增强调试

    // 牺牲了构建速度的sourcemap是最详细的

  

  (8)context基础目录,绝对路径,用于从配置中解析入口起点(entry point)和loader:

  

  context: __dirname, // string(绝对路径!)

  

  (9)target构建目标:

  

    target: "web",                         // 枚举  target: "webworker", // WebWorker

    target: "webworker"                //webworker

    target: "node",                       // Node.js 通过require加载模块

    target: "async-node",                     // Node.js 通过fs和vm加载分块

    target: "node-webkit",            // 编译为webkit可用,并且用jsonp去加载分块

    target: "electron-main",         // electron,主进程(main process)

    target: "electron-renderer",           // electron,渲染进程(renderer process)

    target: (compiler) => { /* ... */ },      // 自定义

  

  (10)externals外部拓展:

  

    externals: ["react", /^@angular\//],  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 }

  

  (11)stats统计信息:

  

    stats: "errors-only", 

    stats: { //object

      assets: true,

      colors: true,

      errors: true,

      errorDetails: true,

      hash: true,

      ...

    },

  

  (12)devServer配置本地运行环境:

  

    devServer: {

      proxy: {                              // 服务器代理

        '/api': 'http://localhost:3000'

      },

      contentBase: path.join(__dirname, 'public'), // boolean、string或array,

      服务器资源根目录

      compress: true,                         // 启用gzip压缩

      historyApiFallback: true,      // 返回404页面时定向到特定页面

      ...

    },

  

  (13)plugins插件:

  

    plugins: [

      ...

    ],

  

  (14)其他插件:

    // 附加插件列表

    /* 高级配置(点击展示) */ 

    resolveLoader: { /* 等同于 resolve */ }

    // 独立解析选项的 loader

    parallelism: 1,                                // number

    // 限制并行处理模块的数量

    profile: true,                                  // boolean数据类型

    // 捕获时机信息

    bail: true, //boolean

    // 在第一个错误出错时抛出,而不是无视错误

    cache: false, // boolean

    // 禁用/启用缓存

    watch: true, // boolean

    // 启用观察

    watchOptions: {

      aggregateTimeout: 1000,                  // in ms毫秒单位

      // 将多个更改聚合到单个重构建(rebuild)

      poll: true,

      poll: 500,                                          // 间隔单位ms

      // 启用轮询观察模式

      // 必须用在不通知更改的文件系统中

      // 即 nfs shares(Network FileSystem)

    },

    node: {

      // Polyfills和mocks可以在非Node环境中运行Node.js环境代码

      // environment code in non-Node environments.

      console: false,                     // boolean | "mock"布尔值或"mock"

      global: true,                // boolean | "mock"布尔值或"mock"

      process: true,                     // boolean布尔值

      __filename: "mock",            // boolean | "mock"布尔值或"mock"

      __dirname: "mock",             // boolean | "mock"布尔值或"mock"

      Buffer: true,                 // boolean | "mock"布尔值或"mock"

      setImmediate: true      // boolean | "mock" | "empty"布尔值或"mock"或"empty"

    },

    recordsPath: path.resolve(__dirname, "build/records.json"),

    recordsInputPath: path.resolve(__dirname, "build/records.json"),

    recordsOutputPath: path.resolve(__dirname, "build/records.json"),

    // TODO

  }

  

  更多详情可请访问Webpack官方网站https://webpack.js.org/。当然读者也可以直接使用Facebook官方提供的create-react-app进行搭建(https://github.com/facebook/create- react-app)。后面章节会继续介绍Webpack真实项目的搭建与实践开发。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。