webpack4 重要更新

webpack4 重要更新

翻译自: github.com/webpack/webp
原文链接: wangwl.net/static/pages

翻译的过程中,发现自己对于webpack有相当相当相当多的知识盲区,如有错误之处,还请大家能够在评论中指出,十分感谢。



Big changes

1. Environment

不再支持Node.js 4。 源码升级到ecmascript的更高版本。

2. Usage

  • 必须选择(mode 或 --mode)一个模式: 'development' 或 'production' 。
    • production下启用所有优化以生成最佳的bundle。
    • development下启用注释和提示,以及eval模式的devtool
      • WIP: addition hints in development mode
    • production不支持监听,development下优化了重新构建的速度。
    • production启用了模块作用域提升
    • 可以通过optimization.*优化各种细节
    • 在构建时会设置process.env.NODE_ENV为production或development
    • 有一个隐藏的none模式,用于关闭所有优化。

3. Syntax

  • import()总是返回一个对象。CommonJS模块会被封装在default属性中。详细参考这里
    • 如果你是通过import()导入CommonJS模块,升级webpack4可能会不兼容。

4. Configuration

  • 不再需要以下插件,换句话说,以下插件功能已经内置在webpack4中:
    • NoEmitOnErrorsPlugin -> optimization.noEmitOnErrors (on by default in production mode)
    • ModuleConcatenationPlugin -> optimization.concatenateModules (on by default in production mode)
    • NamedModulesPlugin -> optimization.namedModules (on by default in develoment mode)
  • CommonsChunkPlugin was removed -> optimization.splitChunks, optimization.runtimeChunk

5. JSON

  • webpack4支持对JSON的处理
  • 允许使用ESM语法导入JSON
    • 对于JSON模块,会删除未使用属性。

6.Optimization

  • uglifyjs-webpack-plugin插件使用1.x版本
    • 支持ES15


Big features

1. Modules

  • webpack目前支持以下模块类型:
    • javascript/auto: (webpack3中的默认值) 支持所有JS模块系统(module system): CommonJS, AMD, ESM
    • javascript/esm: EcmaScript模块,不支持其他文件系统。
    • javascript/dynamic: Only CommonJS and, EcmaScript modules are not available
    • json: JSON 数据, 可以通过require 和 import 方式使用。
    • webassembly/experimental: WebAssembly 模块 (currently experimental)
  • javascript/esm处理ESM比javascript/auto更严格(strictly):
    • Imported names need to exist on imported module
    • Dynamic modules (non-esm, i. e. CommonJs) can only imported via default import, everything else (including namespace import) emit errors
  • .mjs模块中默认使用javascript/esm
  • WebAssembly 模块
    • 可以导入其他模块(JS和WASM)
    • 在ESM中导入WebAssembly模块会进行验证
      • 当试图导入WASM中的某个值,但在WASM模块中未暴露该值的话,会收到警告/错误。
    • 只能用于异步chunk,不能够直接用在初始的chunk中。(对web性能不好)
      • 通过import()导出WASM模块

2. Optimization

  • 支持在package.json中设置sideEffects:false
    • 并且支持sideEffects设置为glob表达式或者glob表达式数组
  • 使用JSONP数组代替JSONP函数 -> 异步支持
  • optimization.splitChunks新的参数介绍: gist.github.com/sokra/1
  • webpack内置移除不可达代码(dead code)功能
    • Before: 通过Uglify移除dead code
    • Now: webpack移除dead code(一般情况下)
    • 可以防止在dead code 中进行import()从而导致代码崩溃

3. Syntax

  • import()支持注释参数webpackExcludewebpackExclude, 用来在使用动态表达式时过滤文件。在webpack3中支持的注释参数有webpackChunkName和webpackMode
  • 使用System.import()会发出警告
    • 通过Rule.parser.system: true关闭警告
    • 通过Rule.parser.system: false禁用System.import

4. Configuration

  • 可以通过module.rules[].resolve配置解析,会和全局的配置合并。
  • 通过optimization.minimize控制文件压缩开关
    -默认: production模式时启用压缩,development模式时关闭压缩
  • 通过optimization.minimizer配置minimizers和参数(即实例化一个新的UglifyJSPlugin)

5. Usage

  • 一些插件的参数现在需要验证(Some Plugin options are now validated)
    • WIP: Better output, no process exit, stack trace, more plugins
  • CLI迁移到webpack-cli中,如果要使用命令行则需要另外安装webpack-cli
  • ProgressPlugin(--progress)目前会显示插件名称
    • 至少已迁移适配webpack4的插件都已支持

6. Performance

  • UglifyJs默认打开cache和parallel
  • 多处性能的提升,尤其是增量构建变得更快
  • 优化了RemoveParentModulesPlugin性能

7. Stats

  • 支持显示嵌套在串联模块中统计信息。


Features

1. Configuration

  • 对于mjs,json和wasm扩展名会自动判断模块类型,对于其他扩展需要通过module.rules[].type配置.
  • 不正确的options.dependencies配置会抛出错误
  • sideEffects可以被module.rules重写
  • 支持output.hashFunction为一个构造函数
    • 出于性能考虑也可以提供一个不加密的hash函数
  • 添加output.globalObject配置参数(to allow to choose the global object reference in runtime exitCode)

2. Runtime

  • chunk加载时的错误包含更多信息,以及两个新的属性typerequest.

3. Devtool

  • remove comment footer from SourceMaps and eval
  • add support for include test and exclude to the eval source map devtool plugin

4. Performance

  • webpack AST可以直接在loader和webpack中传递,以避免额外的解析
  • 没有使用的模块不再进行串联提升
  • 添加ProfilingPlugin,该插件会写入一个(chrome)配置文件(profile file),该配置文件包含插件的相关时间信息。
  • 使用for of替换forEach
  • 使用MapSet替换Object
  • 使用includes替换indexof
  • 使用字符串方法替换掉一些正则
  • 队列中同一个job不再入队两次
  • 默认使用更快的md4哈希

5. Optimization

  • 当导出超过25个属性时候,会更改为更短的名称(一般为单字符)。 (*这个优化点个人测试了下,貌似没什么效果,有空再试试)
  • script标签不再添加text/javascriptasync,因为这两个属性为默认值。
  • 减少了以点模块串联的代码
  • 常量替换目前不需要使用__webpack_require__

6. Defaults

  • webpack文件查找按照以下顺序: .wasm, .mjs, .js.json
  • output.pathinfo在development模式下默认为true
  • production模式下默认关闭内存缓存
  • entry默认为./src
  • output.path默认为./dist
  • 省略mode参数时,默认为production模式

7. Usage

  • Add detailed progress reporting to SourceMapDevToolPlugin
  • emoved plugins now give a useful error message

8. Stats

  • 在统计中,字节单位使用kiB代替kB
  • entrypoints 默认为true
  • chunk显示<{parent}>>{children}<={siblings}=
  • 统计中添加buildAt时间
  • 统计json生成在输出路径中

9. Syntax

  • A resource query is supported in context
  • import()中引用入口点名称(entry point name), 会发出错误而不再是警告。
  • 升级使用acorn 5.x ,支持ES 2018

10. Plugins

  • done更改为异步事件


Removed features

  • removed module.loaders
  • removed loaderContext.options
  • removed Compilation.notCacheable flag
  • removed NoErrorsPlugin
  • removed Dependency.isEqualResource
  • removed NewWatchingPlugin
  • removed CommonsChunkPlugin


Breaking changes for plugins/loaders

  • 新的插件系统
    • plugin向后兼容
    • 在webpack4中,插件应当使用Compiler.hooks.xxx.tap(<plugin name>, fn)
  • 使用新版本的enhanced-resolve
  • chunk Template 目前会生成多个资源(multiple assets)
  • Chunk.chunks/parents/blocks不再使用Array,而使用Set
  • Parser.scope.renamesParser.scope.definitions 不再是Objects/Arrays , 使用 Map/Sets 代替.
  • 解析器使用StackedSetMap (类LevelDB的数据结构) 代替 Array.
  • 调用插件的时候不再设置Compiler.options
  • Harmony Dependencies has changed because of refactoring
  • Dependency.getReference()返回weak属性,在getReference()的base impl中返回; Dependency.weakDependency基类使用。
  • 所有模块(module)的构造函数的参数发生变化。
  • 合并ContextModuleresolveDependencies参数
  • 更改并重命名import()的依赖(dependencies)
  • Compiler.resolvers移动到Compiler.resolverFactory,可以通过插件进行访问
  • 使用Dependency.getResourceIdentifier代替Dependency.isEqualResource
  • Template上的方法目前为静态方法
  • 添加RuntimeTemplate类,并且将outputOptionsrequestShortener移动到该类中
    • 已经更新许多方法,使用RuntimeTemplate代替
    • 我们计划将访问运行时的代码移动到该类中
  • Module.buildMeta代替Module.meta
  • 添加Module.buildInfoModule.factoryMeta
  • 移动Module上的一些属性到新的对象上。
  • 添加loaderContext.rootContext指向context。Loader可以通过该相对于应用程序根节点(application root)做一些事情。
  • 当启用HMR时,在content中添加this.hot
  • uildMeta.exportsType: "namespace代替buildMeta.harmony
  • chunk图的更改:
    • Before: chunk相互之间是父子关系
    • Now: Chunk按顺序排列在ChunkGroups中,ChunkGroup相互之间是父子关系。
    • Before: AsyncDependenciesBlocks引用一个Chunk列表
    • Now: AsyncDependenciesBlocks引用一个ChunkGroup
  • file/contextTimestamps为Map类型
  • map/foreachChunks/Modules/Parents 方法已经弃用/移除
  • NormalModule的构造函数接受对象参数
  • NormalModule添加必须的generator参数
  • NormalModuleFactory添加createGeneratorgenerator事件钩子 (to customize code generation).
  • 可以通过事件钩子自定义Chunk的渲染manifest.
编辑于 2018-03-07