前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >webpack配置完全指南_2023-03-01

webpack配置完全指南_2023-03-01

原创
作者头像
gogo2027
发布于 2023-03-01 13:11:03
发布于 2023-03-01 13:11:03
3.6K00
代码可运行
举报
运行总次数:0
代码可运行

前言

对于入门选手来讲,webpack 配置项很多很重,如何快速配置一个可用于线上环境的 webpack 就是一件值得思考的事情。其实熟悉 webpack 之后会发现很简单,基础的配置可以分为以下几个方面: entryoutputmoderesolvemoduleoptimizationpluginsource mapperformance 等,本文就来重点分析下这些部分。

一、配置入口 entry

1、单入口和多入口

将源文件加入到 webpack 构建流程,可以是单入口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  entry: `./index.js`,
}

构建包名称 [name]main

或多入口:

代码语言:java
AI代码解释
复制
module.exports = {
  entry: { 
    "index": `./index.js`,
  },
}

key:value 键值对的形式:

  • key:构建包名称,即 [name] ,在这里为 index
  • value:入口路径

入口决定 webapck 从哪个模块开始生成依赖关系图(构建包),每一个入口文件都对应着一个依赖关系图。

2. 动态配置入口文件
动态打包所有子项目

当构建项目包含多个子项目时,每次增加一个子系统都需要将入口文件写入 webpack 配置文件中,其实我们让webpack 动态获取入口文件,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 使用 glob 等工具使用若干通配符,运行时获得 entry 的条目
module.exports = {
  entry: glob.sync('./project/**/index.js').reduce((acc, path) => {
    const entry = path.replace('/index.js', '')
    acc[entry] = path
    return acc
  }, {}),
}

则会将所有匹配 ./project/**/index.js 的文件作为入口文件进行打包,如果你想要增加一个子项目,仅仅需要在 project 创建一个子项目目录,并创建一个 index.js 作为入口文件即可。

这种方式比较适合入口文件不集中且较多的场景。

动态打包某一子项目

在构建多系统应用或组件库时,我们每次打包可能仅仅需要打包某一模块,此时,可以通过命令行的形式请求打印某一模块,例如:

代码语言:text
AI代码解释
复制
npm run build --project components

在打包的时候解析命令行参数:

代码语言:text
AI代码解释
复制
// 解析命令行参数
const argv = require('minimist')(process.argv.slice(2))
// 项目
const project = argv['project'] || 'index'

然后配置入口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  entry: { 
    "index": `./${project}/index.js`,
  } 
}

相当于:

代码语言:java
AI代码解释
复制
module.exports = {
  entry: { 
    "index": `./components/index.js`,
  } 
}

当然,你可以传入其它参数,也可以应用于多个地方,例如 resolve.alias 中。

二、配置出口 output

用于告知 webpack 如何构建编译后的文件,可以自定义输出文件的位置和名称:

代码语言:java
AI代码解释
复制
module.exports = {
  output: { 
    // path 必须为绝对路径
    // 输出文件路径
    path: path.resolve(__dirname, '../../dist/build'),
    // 包名称
    filename: "[name].bundle.js",
    // 或使用函数返回名(不常用)
    // filename: (chunkData) => {
    //   return chunkData.chunk.name === 'main' ? '[name].js': '[name]/[name].js';
    // },
    // 块名,公共块名(非入口)
    chunkFilename: '[name].[chunkhash].bundle.js',
    // 打包生成的 index.html 文件里面引用资源的前缀
    // 也为发布到线上资源的 URL 前缀
    // 使用的是相对路径,默认为 ''
    publicPath: '/', 
  }
}

在 webpack4 开发模式下,会默认启动 output.pathinfo ,它会输出一些额外的注释信息,对项目调试非常有用,尤其是使用 eval devtool 时。

filename[name] 为 entry 配置的 key,除此之外,还可以是 [id] (内部块 id )、 [hash][contenthash] 等。

1. 浏览器缓存与 hash 值

对于我们开发的每一个应用,浏览器都会对静态资源进行缓存,如果我们更新了静态资源,而没有更新静态资源名称(或路径),浏览器就可能因为缓存的问题获取不到更新的资源。在我们使用 webpack 进行打包的时候,webpack 提供了 hash 的概念,所以我们可以使用 hash 来打包。

在定义包名称(例如 chunkFilenamefilename),我们一般会用到哈希值,不同的哈希值使用的场景不同:

hash

build-specific, 哈希值对应每一次构建( Compilation ),即每次编译都不同,即使文件内容都没有改变,并且所有的资源都共享这一个哈希值,此时,浏览器缓存就没有用了,可以用在开发环境,生产环境不适用。

chunkhash

chunk-specific, 哈希值对应于 webpack 每个入口点,每个入口都有自己的哈希值。如果在某一入口文件创建的关系依赖图上存在文件内容发生了变化,那么相应入口文件的 chunkhash 才会发生变化,适用于生产环境

contenthash

content-specific,根据包内容计算出的哈希值,只要包内容不变,contenthash 就不变,适用于生产环境

webpack 也允许哈希的切片。如果你写 [hash:8] ,那么它会获取哈希值的前 8 位。

注意:
  • 尽量在生产环境使用哈希
  • 按需加载的块不受 filename 影响,受 chunkFilename 影响
  • 使用 hash/chunkhash/contenthash 一般会配合 html-webpack-plugin (创建 html ,并捆绑相应的打包文件) 、clean-webpack-plugin (清除原有打包文件) 一起使用。
2. 打包成库

当使用 webapck 构建一个可以被其它模块引用的库时:

代码语言:java
AI代码解释
复制
module.exports = {
  output: { 
    // path 必须为绝对路径
    // 输出文件路径
    path: path.resolve(__dirname, '../../dist/build'),
    // 包名称
    filename: "[name].bundle.js",
    // 块名,公共块名(非入口)
    chunkFilename: '[name].[chunkhash].bundle.js',
    // 打包生成的 index.html 文件里面引用资源的前缀
    // 也为发布到线上资源的 URL 前缀
    // 使用的是相对路径,默认为 ''
    publicPath: '/', 
    // 一旦设置后该 bundle 将被处理为 library
    library: 'webpackNumbers',
    // export 的 library 的规范,有支持 var, this, commonjs,commonjs2,amd,umd
    libraryTarget: 'umd',
  }
}

三、配置模式 mode(webpack4)

设置 mode ,可以让 webpack 自动调起相应的内置优化。参考 前端进阶面试题详细解答

代码语言:java
AI代码解释
复制
module.exports = {
  // 可以是 none、development、production
  // 默认为 production
  mode: 'production'
}

或在命令行里配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"build:prod": "webpack --config config/webpack.prod.config.js --mode production"

在设置了 mode 之后,webpack4 会同步配置 process.env.NODE_ENVdevelopmentproduction

webpack4 最引人注目的主要是:

  • 减小编译时间

打包时间减小了超过 60%

  • 零配置

我们可以在没有任何配置文件的情况下将 webpack 用于各种项目

webpack4 支持零配置使用,这里的零配置就是指,mode 以及 entry (默认为 src/index.js)都可以通过入口文件指定,并且 webpack4 针对对不同的 mode 内置相应的优化策略。

1. production

配置:

代码语言:java
AI代码解释
复制
// webpack.prod.config.js
module.exports = {
  mode: 'production',
}

相当于默认内置了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// webpack.prod.config.js
module.exports = {
  performance: {
    // 性能设置,文件打包过大时,会报警告
    hints: 'warning'
  },
  output: {
    // 打包时,在包中不包含所属模块的信息的注释
    pathinfo: false
  },
  optimization: {
    // 不使用可读的模块标识符进行调试
    namedModules: false,
    // 不使用可读的块标识符进行调试
    namedChunks: false,
    // 设置 process.env.NODE_ENV 为 production
    nodeEnv: 'production',
    // 标记块是否是其它块的子集
    // 控制加载块的大小(加载较大块时,不加载其子集)
    flagIncludedChunks: true,
    // 标记模块的加载顺序,使初始包更小
    occurrenceOrder: true,
    // 启用副作用
    sideEffects: true,
    // 确定每个模块的使用导出,
    // 不会为未使用的导出生成导出
    // 最小化的消除死代码
    // optimization.usedExports 收集的信息将被其他优化或代码生成所使用
    usedExports: true,
    // 查找模块图中可以安全的连接到其它模块的片段
    concatenateModules: true,
    // SplitChunksPlugin 配置项
    splitChunks: {
      // 默认 webpack4 只会对按需加载的代码做分割
      chunks: 'async',
      // 表示在压缩前的最小模块大小,默认值是30kb
      minSize: 30000,
      minRemainingSize: 0,
      // 旨在与HTTP/2和长期缓存一起使用 
      // 它增加了请求数量以实现更好的缓存
      // 它还可以用于减小文件大小,以加快重建速度。
      maxSize: 0,
      // 分割一个模块之前必须共享的最小块数
      minChunks: 1,
      // 按需加载时的最大并行请求数
      maxAsyncRequests: 6,
      // 入口的最大并行请求数
      maxInitialRequests: 4,
      // 界定符
      automaticNameDelimiter: '~',
      // 块名最大字符数
      automaticNameMaxLength: 30,
      cacheGroups: { // 缓存组
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    },
    // 当打包时,遇到错误编译,将不会把打包文件输出
    // 确保 webpack 不会输入任何错误的包
    noEmitOnErrors: true,
    checkWasmTypes: true,
    // 使用 optimization.minimizer || TerserPlugin 来最小化包
    minimize: true,
  },
  plugins: [
    // 使用 terser 来优化 JavaScript
    new TerserPlugin(/* ... */),
    // 定义环境变量
    new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
    // 预编译所有模块到一个闭包中,提升代码在浏览器中的执行速度
    new webpack.optimize.ModuleConcatenationPlugin(),
    // 在编译出现错误时,使用 NoEmitOnErrorsPlugin 来跳过输出阶段。
    // 这样可以确保输出资源不会包含错误
    new webpack.NoEmitOnErrorsPlugin()
  ]
}
2. development

配置:

代码语言:java
AI代码解释
复制
// webpack.dev.config.js
module.exports = {
  mode: 'development',
}

相当于默认内置了:

代码语言:java
AI代码解释
复制
// webpack.dev.config.js
module.exports = {
  devtool: 'eval',
  cache: true,
  performance: {
    // 性能设置,文件打包过大时,不报错和警告,只做提示
    hints: false
  },
  output: {
    // 打包时,在包中包含所属模块的信息的注释
    pathinfo: true
  },
  optimization: {
    // 使用可读的模块标识符进行调试
    namedModules: true,
    // 使用可读的块标识符进行调试
    namedChunks: true,
    // 设置 process.env.NODE_ENV 为 development
    nodeEnv: 'development',
    // 不标记块是否是其它块的子集
    flagIncludedChunks: false,
    // 不标记模块的加载顺序
    occurrenceOrder: false,
    // 不启用副作用
    sideEffects: false,
    usedExports: false,
    concatenateModules: false,
    splitChunks: {
      hidePathInfo: false,
      minSize: 10000,
      maxAsyncRequests: Infinity,
      maxInitialRequests: Infinity,
    },
    // 当打包时,遇到错误编译,仍把打包文件输出
    noEmitOnErrors: false,
    checkWasmTypes: false,
    // 不使用 optimization.minimizer || TerserPlugin 来最小化包
    minimize: false,
    removeAvailableModules: false
  },
  plugins: [
    // 当启用 HMR 时,使用该插件会显示模块的相对路径
    // 建议用于开发环境
    new webpack.NamedModulesPlugin(),
    // webpack 内部维护了一个自增的 id,每个 chunk 都有一个 id。
    // 所以当增加 entry 或者其他类型 chunk 的时候,id 就会变化,
    // 导致内容没有变化的 chunk 的 id 也发生了变化
    // NamedChunksPlugin 将内部 chunk id 映射成一个字符串标识符(模块的相对路径)
    // 这样 chunk id 就稳定了下来
    new webpack.NamedChunksPlugin(),
    // 定义环境变量
    new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
  ]
}
3. none

不进行任何默认优化选项。

配置:

代码语言:java
AI代码解释
复制
// webpack.com.config.js
module.exports = {
  mode: 'none',
}

相当于默认内置了:

代码语言:yaml
AI代码解释
复制
// webpack.com.config.js
module.exports = {
  performance: {
   // 性能设置,文件打包过大时,不报错和警告,只做提示
   hints: false
  },
  optimization: {
    // 不标记块是否是其它块的子集
    flagIncludedChunks: false,
    // 不标记模块的加载顺序
    occurrenceOrder: false,
    // 不启用副作用
    sideEffects: false,
    usedExports: false,
    concatenateModules: false,
    splitChunks: {
      hidePathInfo: false,
      minSize: 10000,
      maxAsyncRequests: Infinity,
      maxInitialRequests: Infinity,
    },
    // 当打包时,遇到错误编译,仍把打包文件输出
    noEmitOnErrors: false,
    checkWasmTypes: false,
    // 不使用 optimization.minimizer || TerserPlugin 来最小化包
    minimize: false,
  },
  plugins: []
}
4. production、 development、none 总结

production 模式下给你更好的用户体验:

  • 较小的输出包体积
  • 浏览器中更快的代码执行速度
  • 忽略开发中的代码
  • 不公开源代码或文件路径
  • 易于使用的输出资产

development 模式会给予你最好的开发体验:

  • 浏览器调试工具
  • 快速增量编译可加快开发周期
  • 运行时提供有用的错误消息

尽管 webpack4 在尽力让零配置做到更多,但仍然是有限度的,大多数情况下还是需要一个配置文件。我们可以在项目的初期使用零配置,在后期业务复杂的时候再配置。

5. 环境变量 process.env.NODE_ENV

第三方框架或库,以及我们的业务代码,都会针对不同的环境配置,执行不同的逻辑代码,例如:

我们可以通过以下方式定义环境变量:

方法一:webpack4 中 mode: 'production' 已经默认配置了 process.env.NODE_ENV = 'production' ,所以 webapck4 可以不定义

尽管 webpack4 中定义 mode 会自动配置 process.env.NODE_ENV ,那么我们就不需要手动配置环境变量了吗?

其实不然,mode 只可以定义成 developmentproduction ,而在项目中,我们不仅仅只有开发或生产环境,很多情况下需要配置不同的环境(例如测试环境),此时我们就需要手动配置其它环境变量(例如测试环境,就需要定义 process.env.NODE_ENV'test' ),你可以采取以下方式:

方法二:webpack.DefinePlugin

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// webpack编译过程中设置全局变量process.env
new webpack.DefinePlugin({
  'process.env': require('../config/dev.env.js')
}

config/prod.env.js

代码语言:java
AI代码解释
复制
module.exports ={
  // 或  '"production"' ,环境变量的值需要是一个由双引号包裹的字符串
  NODE_ENV: JSON.stringify('production') 
}

方法三:webpack 命令时, NODE_ENV=development

在 window 中配置 NODE_ENV=production 可能会卡住,所以使用 cross-env:

代码语言:text
AI代码解释
复制
cross-env NODE_ENV=production webpack --config webpack.config.prod.js

方法四:使用 new webpack.EnvironmentPlugin(['NODE_ENV'])

EnvironmentPlugin 是一个通过 webpack.DefinePlugin 来设置 process.env 环境变量的快捷方式。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new webpack.EnvironmentPlugin({
  NODE_ENV: 'production',
});

注意:上面其实是给 NODE_ENV 设置一个默认值 'production' ,如果其它地方有定义 process.env.NODE_ENV ,则该默认值无效。

四、配置解析策略 resolve

自定义寻找依赖模块时的策略(例如 import _ from 'lodash'):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  resolve: {
    // 设置模块导入规则,import/require时会直接在这些目录找文件
    // 可以指明存放第三方模块的绝对路径,以减少寻找,
    // 默认 node_modules
    modules: [path.resolve(`${project}/components`), 'node_modules'],
    // import导入时省略后缀
    // 注意:尽可能的减少后缀尝试的可能性
    extensions: ['.js', '.jsx', '.react.js', '.css', '.json'],
    // import导入时别名,减少耗时的递归解析操作
    alias: {
      '@components': path.resolve(`${project}/components`),
      '@style': path.resolve('asset/style'),
    },
    // 很多第三方库会针对不同的环境提供几份代码
    // webpack 会根据 mainFields 的配置去决定优先采用那份代码
    // 它会根据 webpack 配置中指定的 target 不同,默认值也会有所不同
    mainFields: ['browser', 'module', 'main'],
  },
}

五、配置解析和转换文件的策略 module

决定如何处理项目中不同类型的模块,通常是配置 module.rules 里的 Loader:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  module: {
    // 指明 webpack 不去解析某些内容,该方式有助于提升 webpack 的构建性能
    noParse: /jquery/,
    rules: [
      {
        // 这里编译 js、jsx
        // 注意:如果项目源码中没有 jsx 文件就不要写 /\.jsx?$/,提升正则表达式性能
        test: /\.(js|jsx)$/,
        // 指定要用什么 loader 及其相关 loader 配置
        use: {
          loader: "babel-loader",
          options: {
            // babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启
            // 使用 cacheDirectory 选项将 babel-loader 的速度提高2倍
              cacheDirectory: true,
              // Save disk space when time isn't as important
              cacheCompression: true,
              compact: true,     
          }
        },
        // 排除 node_modules 目录下的文件
        // node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
        exclude: /node_modules/
        // 也可以配置 include:需要引入的文件
      }
    ]
  }
}
1. noParse

指明 webpack 不去解析某些内容,该方式有助于提升 webpack 的构建性能。

2. rules

常见的 loader 有:

  • babel-loader:解析 .js.jsx 文件
代码语言:javascript
代码运行次数:0
运行
复制

// 配置 .babelrc

{

代码语言:txt
AI代码解释
复制
"presets": [
代码语言:txt
AI代码解释
复制
  [
代码语言:txt
AI代码解释
复制
    "@babel/preset-env",
代码语言:txt
AI代码解释
复制
  ],
代码语言:txt
AI代码解释
复制
  "@babel/preset-react"
代码语言:txt
AI代码解释
复制
],
代码语言:txt
AI代码解释
复制
"plugins": [
代码语言:txt
AI代码解释
复制
  [
代码语言:txt
AI代码解释
复制
    "@babel/plugin-proposal-class-properties",
代码语言:txt
AI代码解释
复制
    {
代码语言:txt
AI代码解释
复制
      "loose": true
代码语言:txt
AI代码解释
复制
    }
代码语言:txt
AI代码解释
复制
  ],
代码语言:txt
AI代码解释
复制
  [
代码语言:txt
AI代码解释
复制
    "@babel/plugin-transform-runtime",
代码语言:txt
AI代码解释
复制
    {
代码语言:txt
AI代码解释
复制
      "absoluteRuntime": false,
代码语言:txt
AI代码解释
复制
      "corejs": false,
代码语言:txt
AI代码解释
复制
      "helpers": true,
代码语言:txt
AI代码解释
复制
      "regenerator": true,
代码语言:txt
AI代码解释
复制
      "useESModules": false
代码语言:txt
AI代码解释
复制
    }
代码语言:txt
AI代码解释
复制
  ],
代码语言:txt
AI代码解释
复制
]

}

代码语言:txt
复制
  • tsx-loader:处理 ts 文件
  • less-loader:处理 less 文件,并将其编译为 css
  • sass-loader:处理 sass、scss 文件,并将其编译为 css
  • postcss-loader
代码语言:java
复制

// postcss.config.js

module.exports = { // 解析CSS文件并且添加浏览器前缀到 CSS 内容里

代码语言:txt
AI代码解释
复制
  plugins: [require('autoprefixer')],

};

代码语言:txt
复制
  • css-loader:处理 css 文件
  • style-loader:将 css 注入到 DOM
  • file-loader:将文件上的import / require 解析为 url,并将该文件输出到输出目录中
  • url-loader:用于将文件转换成 base64 uri 的 webpack 加载程序
  • html-loader:将 HTML 导出为字符串, 当编译器要求时,将 HTML 最小化

六、配置优化 optimization(webpack4)

webapck4 会根据你所选择的 mode 进行优化,你可以手动配置,它将会覆盖自动优化

主要涉及两方面的优化:

  • 最小化包
  • 拆包
1. 最小化包
  • 使用 optimization.removeAvailableModules 删除已可用模块
  • 使用 optimization.removeEmptyChunks 删除空模块
  • 使用 optimization.occurrenceOrder 标记模块的加载顺序,使初始包更小
  • 使用 optimization.providedExportsoptimization.usedExportsconcatenateModulesoptimization.sideEffects 删除死代码
  • 使用 optimization.splitChunks 提取公共包
  • 使用 optimization.minimizer || TerserPlugin 来最小化包
2. 拆包

当包过大时,如果我们更新一小部分的包内容,那么整个包都需要重新加载,如果我们把这个包拆分,那么我们仅仅需要重新加载发生内容变更的包,而不是所有包,有效的利用了缓存。

拆分 node_modules

很多情况下,我们不需要手动拆分包,可以使用 optimization.splitChunks

代码语言:lua
AI代码解释
复制
const path = require('path');
module.exports = {
  entry: path.resolve(__dirname, 'src/index.js'),
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
  },
  optimization: {
    splitChunks: {
      // 对所有的包进行拆分
      chunks: 'all',
    },
  },
};

我们不必制定拆包策略,chunks: all 会自动将 node_modules 中的所有内容放入一个名为 vendors〜main.js 的文件中。

拆分业务代码
代码语言:css
AI代码解释
复制
module.exports = {
  entry: {
    main: path.resolve(__dirname, 'src/index.js'),
    ProductList: path.resolve(__dirname, 'src/ProductList/ProductList.js'),
    ProductPage: path.resolve(__dirname, 'src/ProductPage/ProductPage.js'),
    Icon: path.resolve(__dirname, 'src/Icon/Icon.js'),
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash:8].js',
  },
};

采用多入口的方式,当有业务代码更新时,更新相应的包即可

拆分第三方库
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: path.resolve(__dirname, 'src/index.js'),
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
  },
  optimization: {
    runtimeChunk: 'single',
    splitChunks: {
      chunks: 'all',
      maxInitialRequests: Infinity,
      minSize: 0,
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name(module) {
            // 获取第三方包名
            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];

            // npm 软件包名称是 URL 安全的,但是某些服务器不喜欢@符号
            return `npm.${packageName.replace('@', '')}`;
          },
        },
      },
    },
  },
};

当第三方包更新时,仅更新相应的包即可。

注意,当包太多时,浏览器会发起更多的请求,并且当文件过小时,对代码压缩也有影响。

动态加载

现在我们已经对包拆分的很彻底了,但以上的拆分仅仅是对浏览器缓存方面的优化,减小首屏加载时间,实际上我们也可以使用按需加载的方式来进一步拆分,减小首屏加载时间:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import React, { useState, useEffect } from 'react';
import './index.scss'

function Main() {
  const [NeighborPage, setNeighborPage] = useState(null)

  useEffect(() => {
    import('../neighbor').then(({ default: component }) => {
      setNeighborPage(React.createElement(component))
    });
  }, [])

  return NeighborPage
    ? NeighborPage
    : <div>Loading...</div>;
}

export default Main

七、配置 plugin

配置 Plugin 去处理及优化其它的需求,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  plugins: [
    // 优化 require
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|zh/),
    // 用于提升构建速度
    createHappyPlugin('happy-babel', [{
      loader: 'babel-loader',
      options: {
        presets: ['@babel/preset-env', "@babel/preset-react"],
        plugins: [
          ['@babel/plugin-proposal-class-properties', {
            loose: true
          }]
        ],
        // babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启
        cacheDirectory: true,
        // Save disk space when time isn't as important
        cacheCompression: true,
        compact: true,
      }
    }])
  ]
}

常用 plugins:

  • html-webpack-plugin:生成 html 文件,并将包添加到 html 中
  • webpack-parallel-uglify-plugin:压缩 js(多进程并行处理压缩)
  • happypack:多线程loader,用于提升构建速度
  • hard-source-webpack-plugin:为模块提供中间缓存步骤,显著提高打包速度
  • webpack-merge:合并 webpack 配置
  • mini-css-extract-plugin:抽离 css
  • optimize-css-assets-webpack-plugin:压缩 css
  • add-asset-html-webpack-plugin:将 JavaScript 或 CSS 资产添加到 html-webpack-plugin 生成的 HTML 中

更多插件可见:plugins

八、配置devtool:source map

配置 webpack 如何生成 Source Map,用来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度:

生产环境:默认为 null ,一般不设置( none )或 nosources-source-map

开发环境:默认为 eval ,一般设置为 evalcheap-eval-source-mapcheap-module-eval-source-map

策略为:

  • 使用 cheap 模式可以大幅提高 souremap 生成的效率。 没有列信息(会映射到转换后的代码,而不是映射到原始代码),通常我们调试并不关心列信息,而且就算 source map 没有列,有些浏览器引擎(例如 v8) 也会给出列信息。
  • 使用 eval 方式可大幅提高持续构建效率。参考官方文档提供的速度对比表格可以看到 eval 模式的编译速度很快。
  • 使用 module 可支持 babel 这种预编译工具(在 webpack 里做为 loader 使用)。

如果默认的 webpack minimizer 已经被重定义(例如 terser-webpack-plugin ),你必须提供 sourceMap:true 选项来启用 source map 支持。

九、配置性能 performance

当打包是出现超过特定文件限制的资产和入口点,performance 控制 webpack 如何通知:

代码语言:java
AI代码解释
复制
module.exports = {
  // 配置如何显示性能提示
  performance: {
    // 可选 warning、error、false
    // false:性能设置,文件打包过大时,不报错和警告,只做提示
    // warning:显示警告,建议用在开发环境
    // error:显示错误,建议用在生产环境,防止部署太大的生产包,从而影响网页性能
    hints: false
  }
}

十、配置其它

1. watch 与 watchOptions
watch

监视文件更新,并在文件更新时重新编译:

代码语言:text
AI代码解释
复制
module.export = {
  // 启用监听模式
  watch: true,
}

webpack-dev-serverwebpack-dev-middleware 中,默认启用了监视模式。

或者我们可以在命令行里启动监听( --watch ):

代码语言:text
AI代码解释
复制
webpack --watch --config webpack.config.dev.js
watchOptions
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.export = {
  watch: true,
  // 自定义监视模式
  watchOptions: {
    // 排除监听
    ignored: /node_modules/,
    // 监听到变化发生后,延迟 300ms(默认) 再去执行动作,
    // 防止文件更新太快导致重新编译频率太高
    aggregateTimeout: 300,
    // 判断文件是否发生变化是通过不停的去询问系统指定文件有没有变化实现的
    // 默认 1000ms 询问一次
    poll: 1000
  }
}
2. externals

排除打包时的依赖项,不纳入打包范围内,例如你项目中使用了 jquery ,并且你在 html 中引入了它,那么在打包时就不需要再把它打包进去:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script
  src="https://code.jquery.com/jquery-3.1.0.js"
  integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
  crossorigin="anonymous">
</script>

配置:

代码语言:java
AI代码解释
复制
module.exports = {
  // 打包时排除 jquery 模块
  externals: {
    jquery: 'jQuery'
  }
};
3.target

构建目标,用于为 webpack 指定一个环境:

代码语言:java
AI代码解释
复制
module.exports = {
  // 编译为类浏览器环境里可用(默认)
  target: 'web'
};
4. cache

缓存生成的 webpack 模块和块以提高构建速度。在开发模式中,缓存设置为 type: 'memory' ,在生产模式中禁用。cache: truecache: {type: 'memory'} 的别名。要禁用缓存传递 false

代码语言:java
AI代码解释
复制
module.exports = {
  cache: false
}

在内存中,缓存仅在监视模式下有用,并且我们假设你在开发中使用监视模式。 在不进行缓存的情况下,内存占用空间较小。

5. name

配置的名称,用于加载多个配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  name: 'admin-app'
};

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
再下一城!“武汉模式”荣获2021信通院数字政府十佳案例
近日,在2021可信云大会上,“数据赋能武汉城市精细化管理”荣获了“数字政府十大创新实践案例”。 作为我国云计算领域最具权威性云计算年会,可信云大会已成功举办八届。2021可信云大会特设“数字政府十大创新实践案例”评选,以更好地展示数字政府优秀建设案例的示范引领作用。 该奖项的荣获,是对武汉智慧模式的认可,也进一步对外展示了武汉新型智慧城市和城市精细化管理领域的建设成效。 一脑统“江城” 武汉市在城市大脑“一网统管”的总体框架和能力支撑下,借助云计算、物联网、大数据、空间信息等新兴技术应用,通过“智
云产品技术支持小助手
2022/06/24
4370
再下一城!“武汉模式”荣获2021信通院数字政府十佳案例
喜报丨武汉荣获“2021世界智慧城市复苏创新大奖”全球冠军
11月17日,2021全球智慧城市大会在西班牙巴塞罗那举行,会上揭晓了全球智慧城市领域的最高奖项——世界智慧城市大奖。 经过层层评选,由腾讯参与建设的武汉智慧城市从世界46个国家421座城市1123份申报材料中脱颖而出,荣获“2021世界智慧城市复苏创新大奖”全球冠军。 全球智慧城市大会创办于2011年,是全球规模最大的专注于城市和社会智慧化发展与转型的智慧城市主题展会。 今年10月15日,武汉以“智慧城市赋能疫后重振,推动超大城市治理创新”为主题,荣获了世界智慧城市(中国区)城市大奖,并代表中国区参加世
云产品技术支持小助手
2022/06/24
3490
喜报丨武汉荣获“2021世界智慧城市复苏创新大奖”全球冠军
重磅!腾讯云参编《城市大脑发展白皮书》正式发布!
1月4日,由全国信标委智慧城市标准工作组牵头,腾讯云等产学研用单位共同参编《城市大脑发展白皮书(2022)》(以下简称“白皮书”)以及《城市大脑案例集(2022)》正式发布。 腾讯云作为业内领先的城市大脑建设服务提供商,基于各地建设实践经验和理论研究,参与了《白皮书》的编写,对我国城市大脑发展建设提供了专业研判及重要贡献。 《城市大脑发展白皮书2022版》 此外,由腾讯云提供技术支持的武汉、广州及上海城市大脑优秀城市综合治理案例被《城市大脑案例集(2022)》收录。 为各地开展城市大脑建设提供场景
云产品技术支持小助手
2022/06/24
1.2K0
重磅!腾讯云参编《城市大脑发展白皮书》正式发布!
“腾讯云WeCity”入选2021世界互联网领先科技成果手册
9月26日,2021年世界互联网大会乌镇峰会在浙江乌镇开幕。“腾讯云WeCity”入选2021世界互联网大会“世界互联网领先科技成果手册”。 本次峰会以“迈向数字文明新时代-携手构建网络空间命运共同体”为主题,聚焦数字赋能、推动深化数字技术合作、完善数字环境治理、共享数字经济红利。 腾讯云WeCity未来城市亮相此次世界互联网大会乌镇峰会,以可视化、可体验的形式展现生活数字化场景,为城市数字化服务提供硬核科技支撑,推进智慧城市发展进程。 在智慧城市实践方面,依托腾讯云底层技术能力打造的“武汉战疫”小
云产品技术支持小助手
2022/06/24
4960
“腾讯云WeCity”入选2021世界互联网领先科技成果手册
武汉市民生服务“一码互联”荣获IDC中国大奖—未来智能领军者
8月26日,由武汉市政务服务和大数据管理局主办、腾讯云提供技术支持的武汉市民生服务“一码互联” 项目摘得了2021年IDC数字化转型—未来智能领军者。 作为我国数字化转型最具权威性的IDC中国大奖,本年度共设置14个奖项类别,全国各地300多家组织机构提交了500多个数字化转型案例,这说明我国数字化转型的成熟度也越来越高。 该奖项的荣获,标志着武汉新型数字化城市进程的升级,也进一步突出对武汉智慧模式的认可,和城市精细化管理领域的建设成效。 国家“十四五”规划和2035年远景目标纲要中提出,加快建设数字经济
云产品技术支持小助手
2022/06/24
5900
武汉市民生服务“一码互联”荣获IDC中国大奖—未来智能领军者
喜报!武汉荣获2021世界智慧城市中国区“城市大奖”!
10月15日晚,2021世界智慧城市大奖(中国区)在上海揭晓,武汉摘得2021世界智慧城市(中国区)大奖! 这也意味着,我们参与建设的武汉智慧城市得到了世界级平台的认可。 全球智慧城市大会(简称SCEWC)创办于2011年,是全球规模最大的专注于城市和社会智慧化发展与转型的智慧城市主题展会。其中世界智慧城市大奖(WSCA)是大会的重要组成版块,被誉为智慧城市行业领域的“奥斯卡”。 本次大赛,武汉以“智慧城市赋能疫后重振,推动超大城市治理创新”为主题,从全国47个省市申报的117个项目中脱颖而出,荣获中国区
云产品技术支持小助手
2022/06/24
5490
喜报!武汉荣获2021世界智慧城市中国区“城市大奖”!
Q2财报亮榜!WeCity持续为城市数字化转型贡献力量
刚刚,腾讯发布2021年第二季度业绩报告,Q2营收为1383亿元,同比增长20%。 本季度,我们加大运用技术及专业经验,助力中小企业、公共服务及公司进行内部协作与外部用户联系,为实体经济乃至整个社会做出贡献。 ——腾讯董事会主席兼首席执行官马化腾 透过财报可以看出,延续腾讯第四次战略升级中提出的“可持续社会价值创新”战略目标,扮演好“数字化助手”的角色,助力社会数字化转型,展现更多社会效益,仍是未来重要的发力点。 而其中,“城市数字化转型”是整体数字化进程中的重要一环。 腾讯云WeCity以“向善的科技力
云产品技术支持小助手
2022/06/24
7850
Q2财报亮榜!WeCity持续为城市数字化转型贡献力量
腾讯WeCity未来城市2.0发布,深入诠释智慧城市运行之道
| 导语 如何在日益复杂化的空间、治理与服务的前提下,践行“市民即用户”“连接即服务”“数据即空间”“城市即平台”的理念。 今年,新冠肺炎疫情成为一次使全球社会始料不及的“黑天鹅”事件,也给我国经济社会发展带来了前所未有的冲击。但同时,疫情也促使业界开始正视不确定性给智慧城市规划和建设带来的影响,并重新思考智慧城市的建设思路与模式。后疫情时代的城市将会继续承载多元社会功能,而环境条件也会日益错综复杂。面对这样的经济社会趋势,预测不是唯一的解决之道,通过“数字优先”布局高效的基础设施和连接能力,构建系统
腾讯大讲堂
2020/09/22
2K0
成都智慧城市规划发布 组件化可视化平台构建城市大脑
到2025年,成都5G基站数达9万个、智慧社区数量达100个、中小学数字校园覆盖率达100%……
物联网数据可视化PaaS平台
2022/06/17
6470
成都智慧城市规划发布 组件化可视化平台构建城市大脑
11月,邀您一起探索数字化转型、智慧城市发展新路径!
距2020年初疫情暴发已经接近两年时间,但武汉“数字抗疫”的故事对于当地市民来说依然历历在目。 2020年2月8日,由腾讯等企业助力上线的“武汉战疫”小程序成为了武汉民众出行的重要凭证。2月10日,武汉全市约90万学生登陆武汉教育空中课堂,进行网络课程学习...... 在后疫情时代,我们看到了数字化的更多可能:线上会议、AI技术、云会展,从“数字抗疫”到“数实融合”,产业互联网的蓬勃发展重塑数字经济新生态、加速了产业数字化转型。 而身处于数字经济洪流中的我们,如何寻找机遇,把握机遇? 11月3日,202
云产品技术支持小助手
2022/06/24
5890
11月,邀您一起探索数字化转型、智慧城市发展新路径!
见证绽放!2021腾讯数字生态大会开启直播预约
今天,武汉市人民政府与腾讯共同向大家宣布: 2021腾讯数字生态大会,正式锁定武汉 8月18日-19日,我们在武汉·中国光谷科技会展中心,邀你一起“数实融合,绽放新机”! 在这个数字技术与实体经济共融共进的新阶段,腾讯将与所有客户、生态合作伙伴、技术开发者、政府及社会组织,共同推动产业发展,绽放用户时代的新机遇。 本次大会将由武汉市人民政府指导,腾讯公司主办,武汉市经济和信息化局、武汉市政务服务和大数据管理局、东湖新技术开发区管委会协办。 腾讯数字生态大会 腾讯数字生态大会是腾讯产业互联网规格最高
腾讯云开发者
2021/07/12
7570
看不见的城市,看得见的人|THINC Webinar
“邑曰筑,都曰城。”《左传》里中国古代有城垣的贵胄都邑封地可称之为城。从中国的镐京、朝歌,到开普敦、雅库茨克和罗马,城初期都是政治和军事的产物,权力创造了城,并决定城的命运。而市,“买卖之所也”,是在人口聚集到一定规模后,人流和物资相互围绕进行交易和集散的地方。 “城”是军事和政治的产物,“市”是经济和生活的产物。由城及市,城市结合,经过几千年的演变,城市从围绕统治者的政治需要到市民生活的经济需要,以人为本,服务于生活的理念,也成了当代城市的核心。 在今天,随着超级大都市的不断形成,似乎城市的命运正在被
云产品技术支持小助手
2022/06/24
4350
看不见的城市,看得见的人|THINC Webinar
城市云脑“与前进者同行”:智慧城市的底座升级与生态进化
据统计,全球在建的智慧城市有800多个,中国就占了一半以上。伴随城市数字转型的深化以及新基建的提速,国内智慧城市建设的热潮此起彼伏——大多数一、二线城市已雏形初现,还有89%的地级市、47%的县级市正厉兵秣马。
IT创事记
2022/08/30
4510
城市云脑“与前进者同行”:智慧城市的底座升级与生态进化
生态大会来啦!探寻未来城市的无限可能,更有双重大礼相送
2021腾讯数字生态大会 火热来袭 作为互联网领域最最最重磅 规格最高、规模最大、覆盖面最广的 年度战略大会 倒计时 5 天! 11月3-4日,武汉光谷会展中心 本次大会全程直播 其中数字政府与智慧城市专场敲定档期! 将于11月3日14:10准时召开 点击👇海报,一键预约云参会 叮 叮 叮 别忘了文末有大彩蛋 免费领公仔、免费领考券(限时限量) 近年来,随着数字化转型升级的不断推进,各行各业纷纷从线下走向线上,为更多城市生活,提供数字化转型解决方案,已经成为智慧城市发展的趋势所需。 那么如何做?谁来做?在
云产品技术支持小助手
2022/06/24
5240
生态大会来啦!探寻未来城市的无限可能,更有双重大礼相送
腾讯携手新乡,共建中部智慧城市新范本
12月16日,腾讯与河南省新乡市人民政府正式达成战略合作,双方将充分发挥各自资源优势,在智慧城市底座、数字惠民体系、数字城市治理等方面开展合作,通过大力增强数字基础设施建设,推动新乡市社会治理数字化,助推数字新乡高质量发展。 腾讯云与新乡市政府签订战略合作 新乡市地处河南省北部,拥有丰厚的历史文化底蕴和旅游资源,交通区位优越,工业及新型展业基础较好,科教优势也非常明显,是中西部地区高校数量较多的非省会城市之一。 “十四五”期间,新乡市将大力夯实新乡新型智慧城市底座,全力塑造新乡数字治理新模式。 助力构建
云产品技术支持小助手
2022/06/24
7860
腾讯携手新乡,共建中部智慧城市新范本
直播预约已开启!2021腾讯数字生态大会让我们“云相聚”| Q推荐
作为中国数字经济建设最重要的产业盛会之一,腾讯数字生态大会将在 2021 年 8 月 18 日 -19 日落地英雄城市武汉。本届腾讯数字生态大会以【数实融合·绽放新机】为主题,汇聚各界行业领袖、技术领军人物、经济学者等共话数字经济的发展趋势,并展现产业互联网的最佳实践成果。 全面聚焦数字经济前沿趋势 2021 腾讯数字生态大会将由 1 场主峰会、1 场技术峰会、40+ 专场,以及 10000㎡智能体验展区等组成。 8 月 18 日的主峰会,将聚焦数字技术与实体经济融合发展趋势,重磅发布《数字化转型指数报告
深度学习与Python
2023/04/01
5510
直播预约已开启!2021腾讯数字生态大会让我们“云相聚”| Q推荐
寻找30位!腾讯云9大政务产品为WeCity加速器注入新势力
打开云法院,调解员、当事人足不出户就能达成远程调解、在线裁决; 进入公众号,村支书开会、村长宣传政策、党员教育等,无需黑板报大喇叭,掌上即可完成; 登录政务网,企业登记、刻章、银行开户、税局领票等环节“最多跑一次”就能办理,还能监督事项进驻状况、给政务服务“打分”…… 从“数字广东”到“一机游云南”、从“蒲城数字乡村“再到“长沙城市超级大脑“, 在建设数字中国的赛道上,腾讯除了依托自身领先的技术积累和连接能力,构建了人工智能(AI)、大数据(Big Data)和云计算(Cloud Computing)为基
腾讯云TStack
2019/11/08
2.4K0
寻找30位!腾讯云9大政务产品为WeCity加速器注入新势力
倒计时2天|武汉,“码”上见!
今天,出发去武汉。 我的武汉朋友小云告诉我,“武汉人很冲,急脾气,过早都来不及坐着吃完”。 但好处也有。比如,刚刚在“i武汉 武汉战疫”小程序提交的办事申请,吃碗面的功夫就搞完了。 不久前,小程序里新增了地铁乘车码功能,每天可以省下许多扫码的步骤和时间。 码,已经成为每个人新的身份标识,是数字生活空间的投影,是智慧城市运行的细胞。 小到个人生活,大到城市治理,点滴变化让武汉变得更加“酷”了。 从“英雄”武汉到“酷”武汉,一切转变是如何发生的? 码,从诞生到互通 “太快了,有点不可思议。” 浙江
云产品技术支持小助手
2022/06/24
5620
倒计时2天|武汉,“码”上见!
以“腾讯云WeCity之名”猜灯谜拿大奖,享中秋佳节!
灯谜一 2021腾讯数字生态大会举办的城市,最具代表性的小吃是什么? A 臭豆腐          B 热干面 C 生煎包          D 胡辣汤 点击下方空白处查看谜底 ▼ 答案:B 数字生态大会是腾讯一年一度最具规格的产业盛会,从科技、文化、产业等不同视角聚焦产业升级、洞察数字经济、共建智慧生态,助力城市经济从高速发展向高质量发展转型。腾讯云WeCity解决方案在人产城融合发展中发挥着重要作用。今年的数字生态大会将于11月3-4日在美丽的武
云产品技术支持小助手
2022/06/24
4840
以“腾讯云WeCity之名”猜灯谜拿大奖,享中秋佳节!
腾讯文旅 邀你武汉见
今天,武汉市人民政府与腾讯共同向大家宣布: 8月18日-19日,我们在武汉·中国光谷科技会展中心,邀你一起“数实融合,绽放新机”! 在这个数字技术与实体经济共融共进的新阶段,腾讯将与所有客户、生态合作伙伴、技术开发者、政府及社会组织,共同推动产业发展,绽放用户时代的新机遇。 本次大会将由武汉市人民政府指导,腾讯公司主办,武汉市经济和信息化局、武汉市政务服务和大数据管理局、东湖新技术开发区管委会协办。 腾讯数字生态大会 腾讯数字生态大会是腾讯产业互联网规格最高、规模最大、覆盖最广的大会,旨在聚焦
腾讯文旅
2021/07/12
8730
推荐阅读
相关推荐
再下一城!“武汉模式”荣获2021信通院数字政府十佳案例
更多 >
LV.0
腾讯云TO B产业生态
目录
  • 前言
  • 一、配置入口 entry
    • 1、单入口和多入口
    • 2. 动态配置入口文件
      • 动态打包所有子项目
      • 动态打包某一子项目
  • 二、配置出口 output
    • 1. 浏览器缓存与 hash 值
      • hash
      • chunkhash
      • contenthash
      • 注意:
    • 2. 打包成库
  • 三、配置模式 mode(webpack4)
    • 1. production
    • 2. development
    • 3. none
    • 4. production、 development、none 总结
    • 5. 环境变量 process.env.NODE_ENV
  • 四、配置解析策略 resolve
  • 五、配置解析和转换文件的策略 module
    • 1. noParse
    • 2. rules
  • 六、配置优化 optimization(webpack4)
    • 1. 最小化包
    • 2. 拆包
      • 拆分 node_modules
      • 拆分业务代码
      • 拆分第三方库
      • 动态加载
  • 七、配置 plugin
  • 八、配置devtool:source map
  • 九、配置性能 performance
  • 十、配置其它
    • 1. watch 与 watchOptions
      • watch
      • watchOptions
    • 2. externals
    • 3.target
    • 4. cache
    • 5. name
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档