Webpack 4 发布,不再支持 Node.js 4
Big changes
- Environment
- Node.js 4 is no longer supported. Source Code was upgraded to a higher ecmascript version.
- Usage
- You have to choose (
mode or --mode) between two modes now: production or development
- production enables all kind of optimizations to generate optimized bundles
- development enables comments and hint for development and enables the eval devtool
- production doesn't support watching, development is optimized for fast incremental rebuilds
- production also enables module concatenating (Scope Hoisting)
- You can configure this in detail with the flags in
optimization.* (build your custom mode)
process.env.NODE_ENV are set to production or development (only in built code, not in config)
- There is a hidden
none mode which disables everything
- Syntax
import() always returns a namespace object. CommonJS modules are wrapped into the default export
- This probably breaks your code, if you used to import CommonJs with
import()
- Configuration
- You no longer need to use these plugins:
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
- JSON
- webpack now handles JSON natively
- You may need to add
type: "javascript/auto" when transforming JSON via loader to JS
- Just using JSON without loader should still work
- allows to import JSON via ESM syntax
- unused exports elimination for JSON modules
- Optimization
- Upgrade uglifyjs-webpack-plugin to v1
Big features
- Modules
- webpack now supports these module types:
- javascript/auto: (The default one in webpack 3) Javascript module with all module systems enabled: CommonJS, AMD, ESM
- javascript/esm: EcmaScript modules, all other module system are not available
- javascript/dynamic: Only CommonJS and, EcmaScript modules are not available
- json: JSON data, it's available via require and import
- webassembly/experimental: WebAssembly modules (currently experimental)
javascript/esm handles ESM more strictly compared to javascript/auto:
- 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
- In
.mjs modules are javascript/esm by default
- WebAssembly modules
- can import other modules (JS and WASM)
- Exports from WebAssembly modules are validated by ESM import
- You'll get a warning/error when trying to import a non-existing export from WASM
- can only be used in async chunks. They doesn't work in initial chunks (would be bad for web performance)
- Import modules using WASM via
import()
- This is an experimental feature and subject of change
- Optimization
sideEffects: false is now supported in package.json
sideEffects in package.json also supports glob expressions and arrays of glob expressions
- Instead of a JSONP function a JSONP array is used -> async script tag support, order no longer matter
- New
optimization.splitChunks option was introduced
Details: gist.github.com/sokra/1522d…
- Dead branches are now removed by webpack itself
- Before: Uglify removed the dead code
- Now: webpack removes the dead code (in some cases)
- This prevents crashing when
import() occur in a dead branch
- Syntax
webpackInclude and webpackExclude are supported by the magic comment for import(). They allow to filter files when using a dynamic expression.
- Using
System.import() now emits a warning
- You can disable the warning with
Rule.parser.system: true
- You can disable
System.import with Rule.parser.system: false
- Configuration
- Resolving can now be configured with
module.rules[].resolve. It's merged with the global configuration.
optimization.minimize has been added to switch minimizing on/off
- By default: on in production mode, off in development mode
optimization.minimizer has been added to configurate minimizers and options
- Usage
- Some Plugin options are now validated
- CLI has been move to webpack-cli, you need to install
webpack-cli to use the CLI
- The ProgressPlugin (
--progress) now displays plugin names
- At least for plugins migrated to the new plugin system
- Performance
- UglifyJs now caches and parallizes by default
- Multiple performance improvements, especially for faster incremental rebuilds
- performance improvement for RemoveParentModulesPlugin
- Stats
- Stats can display modules nested in concatenated modules
Features
- Configuration
- Module type is automatically choosen for mjs, json and wasm extensions. Other extensions need to be configured via
module.rules[].type
- Incorrect
options.dependencies configurations now throw error
sideEffects can be overriden via module.rules
output.hashFunction can now be a Constructor to a custom hash function
- You can provide a non-cryto hash function for performance reasons
- add
output.globalObject config option to allow to choose the global object reference in runtime exitCode
- Runtime
- Error for chunk loading now includes more information and two new properties
type and request.
- Devtool
- remove comment footer from SourceMaps and eval
- add support for
include test and exclude to the eval source map devtool plugin
- Performance
- webpacks AST can be passed directly from loader to webpack to avoid extra parsing
- Unused modules are no longer unnecessarly concatenated
- Add a ProfilingPlugin which write a (Chrome) profile file which includes timings of plugins
- Migrate to using
for of instead of forEach
- Migrate to using
Map and Set instead of Objects
- Migrate to using
includes instead of indexOf
- Replaced some RegExp with string methods
- Queue don't enqueues the same job twice
- Use faster md4 hash for hashing by default
- Optimization
- When using more than 25 exports mangled export names are shorter.
- script tags are no longer
text/javascript and async as this are the default values (saves a few bytes)
- The concatenated module now generates a bit less code
- constant replacements now don't need
__webpack_require__ and argument is omitted
- Defaults
- webpack now looks for the
.wasm, .mjs, .js and .json extensions in this order
output.pathinfo is now on by default in develoment mode
- in-memory caching is now off by default in production
entry defaults to ./src
output.path defaults to ./dist
- Use
production defaults when omiting the mode option
- Usage
- Add detailed progress reporting to SourceMapDevToolPlugin
- removed plugins now give a useful error message
- Stats
- Sizes are now shown in kiB instead of kB in Stats
- entrypoints are now shows by default in Stats
- chunks now display
<{parents}> >{children}< and ={siblings}= in Stats
- add
buildAt time to stats
- stats json now includes the output path
- Syntax
- A resource query is supported in context
- Referencing entry point name in
import() now emits a error instead of a warning
- Upgraded to acorn 5 and support ES 2018
- Plugins
done is now an async hook
Bugfixes
- Generated comments no longer break on
*/
- webpack no longer modifies the passed options object
- Compiler "watch-run" hook now has the Compiler as first parameter
- add
output.chunkCallbackName to the schema to allow configurating WebWorker template
- Using
module.id/loaded now correctly bails out of Module Concatentation (Scope Hoisting)
- OccurenceOrderPlugin now sorts modules in correct order (instead of reversed)
- timestamps for files are read from watcher when calling
Watching.invalidate
- fix incorrect
-! behavior with post loaders
- add
run and watchRun hooks for MultiCompiler
this is now undefined in ESM
- VariableDeclaration are correctly identified as
var, const or let
- Parser now parse the source code with the correct source type (module/script) when the module type
javascript/dynamic or javascript/module is used.
- don't crash on missing modules with
buildMeta of null
- add
original-fs module for electron targets
- HMRPlugin can be added to the Compiler outside of
plugins
Internal changes
- Replaced
plugin calls with tap calls (new plugin system)
- Migrated many deprecated plugins to new plugin system API
- added
buildMeta.exportsType: "default" for json modules
- Remove unused methods from Parser (parserStringArray, parserCalculatedStringArray)
- Remove ability to clear BasicEvaluatedExpression and to have multiple types
- Buffer.from instead of new Buffer
- Avoid using forEach and use for of instead
- Use
neo-async instead of async
- Update tapable and enhanced-resolve dependencies to new major versions
- Use prettier
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
- new plugin system
plugin method is backward-compatible
- Plugins should use
Compiler.hooks.xxx.tap(<plugin name>, fn) now
- New major version of enhanced-resolve
- Templates for chunks may now generate multiple assets
Chunk.chunks/parents/blocks are no longer Arrays. A Set is used internally and there are methods to access it.
Parser.scope.renames and Parser.scope.definitions are no longer Objects/Arrays, but Map/Sets.
- Parser uses
StackedSetMap (LevelDB-like datastructure) instead of Arrays
Compiler.options is no longer set while applying plugins
- Harmony Dependencies has changed because of refactoring
Dependency.getReference() may now return a weak property. Dependency.weak is now used by the Dependency base class and returned in the base impl of getReference()
- Constructor arguments changed for all
Modules
- Merged options into options object for
ContextModule and resolveDependencies
- Changed and renamed dependencies for `import()
- Moved
Compiler.resolvers into Compiler.resolverFactory accessible with plugins
Dependency.isEqualResource has been replaced with Dependency.getResourceIdentifier
- Methods on
Template are now static
- A new RuntimeTemplate class has been added and
outputOptions and requestShortener has been moved to this class
- Many methods has been updated to use the RuntimeTemplate instead
- We plan to move code which accesses the runtime to this new class
Module.meta has been replaced with Module.buildMeta
Module.buildInfo and Module.factoryMeta have been added
- Some properties of
Module have been moved into the new objects
- added
loaderContext.rootContext which points to the context options. Loaders may use it to make stuff relative to the application root.
- add
this.hot flag to loader context when HMR is enabled
buildMeta.harmony has been replaced with buildMeta.exportsType: "namespace
- The chunk graph has changed:
- Before: Chunks were connected with parent-child-relationships.
- Now: ChunkGroups are connected with parent-child-relationships. ChunkGroups contain Chunks in order.
- Before: AsyncDependenciesBlocks reference a list of Chunks in order.
- Now: AsyncDependenciesBlocks reference a single ChunkGroup.
- file/contextTimestamps are Maps now
map/foreach Chunks/Modules/Parents methods are now deprecated/removed
- NormalModule accept options object in Constructor
- Added required generator argument for NormalModule
- Added
createGenerator and generator hooks for NormalModuleFactory to customize code generation
- Allow to customize render manifest for Chunks via hooks