Description
Complete changelog for 4.0.0-alpha.5 compared to version 3:
Items changed from 4.0.0-alpha.4 to 4.0.0-alpha.5 are prefixed with [new]
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
- WIP: addition hints in development mode
- 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
- You have to choose (
- 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()
- This probably breaks your code, if you used to import CommonJs with
- 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)
- [new]
CommonsChunkPlugin
was removed ->optimization.splitChunks
- You no longer need to use these plugins:
- 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
- You may need to add
- allows to import JSON via ESM syntax
- unused exports elimination for JSON modules
- webpack now handles JSON natively
- Optimization
- Upgrade uglifyjs-webpack-plugin to v1
- ES15 support
- 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 strict compared tojavascript/auto
:- Imported names need to exist on imported module
- Non-ESM can only imported via
default
import, everything else (including namespace import) emit errors
- In
.mjs
modulesjavascript/esm
is used
- 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
- webpack now supports these module types:
- Optimization
sideEffects: false
is now supported in package.json- Instead of a JSONP function a JSONP array is used -> async support
- [new] New
optimization.splitChunks
option was introduced
Details: https://gist.github.com/sokra/1522d586b8e5c0f5072d7565c2bee693 - [new] 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
andwebpackExclude
are supported by the magic comment forimport()
. They allow to filter files when using a dynamic expression.- [new] Using
System.import()
now emits a warning- You can disable the warning with
Rule.parser.system: true
- You can disable
System.import
withRule.parser.system: false
- You can disable the warning with
- 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- many config options which support placeholders now also support a function
- Resolving can now be configured with
- Usage
- Some Plugin options are now validated
- WIP: Better output, no process exit, stack trace, more plugins
- 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
- Some Plugin options are now validated
- 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 Rule.ident
is now allowed by schemasideEffects
can be overriden via module.rulesoutput.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
andrequest
.
- Error for chunk loading now includes more information and two new properties
- Performance
- webpacks AST can be passed directly from loader to webpack to avoid extra parsing
- Unused modules are no longer unnecessarly concatenated
- [new] Add a ProfilingPlugin which write a (Chrome) profile file which includes timings of plugins
- [new] Migrate to using
for of
instead offorEach
- [new] Migrate to using
Map
andSet
instead of Objects - [new] Migrate to using
includes
instead ofindexOf
- [new] Replaced some RegExp with string methods
- [new] Queue don't enqueues the same job twice
- Optimization
- When using more than 25 exports mangled export names are shorter.
- script tags are no longer
text/javascript
andasync
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 themode
option
- webpack now looks for the
- Usage
- Add detailed progress reporting to SourceMapDevToolPlugin
- Stats
- Sizes are now shown in kiB instead of kB in Stats
- [new] entrypoints are now shows by default in Stats
- [new] chunks now display
<{parent}>
>{children}<
and={siblings}=
in Stats
- Syntax
- A resource query is supported in context
- Parser now understand
new Foo()
expressions - Parser can now evaluate
**
,&
,|
,^
,>>>
,>>
,<<
and~
- Referencing entry point name in
import()
now emits a error instead of a warning - [new] Upgraded to acorn 5
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
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
- Avoid using
process.exit
and useprocess.exitCode
instead - fix bluebird warning in
webpack/hot/signal
- fix incorrect
-!
behavior with post loaders - add
run
andwatchRun
hooks forMultiCompiler
- [new]
this
is now undefined in ESM - [new] Initial chunks no longer contribute to chunkhash of runtime chunk and hashes don't occur in chunk hash map
- [new] VariableDeclaration are correctly identified as
var
,const
orlet
- [new] Parser now parse the source code with the correct source type (module/script) when the module type
javascript/dynamic
orjavascript/module
is used.
Internal changes
- Replaced
plugin
calls withtap
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
Removed features
- removed
module.loaders
- removed
loaderContext.options
- removed
Compilation.notCacheable
flag - removed
NoErrorsPlugin
- removed
Dependency.isEqualResource
- removed
NewWatchingPlugin
- [new] 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
andParser.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 aweak
property.Dependency.weak
is now used by theDependency
base class and returned in the base impl ofgetReference()
- Constructor arguments changed for all
Module
s - Merged options into options object for
ContextModule
andresolveDependencies
- Changed and renamed dependencies for `import()
- Moved
Compiler.resolvers
intoCompiler.resolverFactory
accessible with plugins Dependency.isEqualResource
has been replaced withDependency.getResourceIdentifier
- Methods on
Template
are now static - A new RuntimeTemplate class has been added and
outputOptions
andrequestShortener
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 withModule.buildMeta
Module.buildInfo
andModule.factoryMeta
have been added- Some properties of
Module
have been moved into the new objects - added
loaderContext.rootContext
which points to thecontext
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 withbuildMeta.exportsType: "namespace
- [new] 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.
Migration
Node.js
If you are still using Node.js 4 or smaller:
Install Node.js 8. You could also install Node.js 6 but it's slower (2x).
CLI
To use the command line interface:
yarn add -D webpack-cli
or
npm install -D webpack-cli
Configuration
// webpack.production.config.js
module.exports = {
+ mode: "production",
plugins: [
- new UglifyJsPlugin(/* ... */),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
- new webpack.optimize.ModuleConcatenationPlugin(),
- new webpack.NoEmitOnErrorsPlugin()
]
}
// webpack.development.config.js
module.exports = {
+ mode: "development",
plugins: [
- new webpack.NamedModulesPlugin(),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
]
}
import()
CommonJs
import()
now always returns the namespace object and not the exports directly for non-ESM.
- import("./commonjs").then(exports => {
+ import("./commonjs").then({ default: exports } => {
// ...
})
Note: ESM modules are not affected.
Note: Babel transpiled ESM (__esModule: true
) will work in .js
modules (javascript/auto), but not in .mjs
modules.
Note: For JSON the same is true, but as JSON modules also export each property as exports you could pick property via destruction.
CommonsChunkPlugin
The following guides try to give 1 to 1 translations for the CommonsChunkPlugin. This does not neccessary fit bet pratices.
Best practise
optimization: {
splitChunks: {
chunks: "all"
}
}
You need to generate the HTML from stats json. Use the entrypoints
property from Stats to know which files to include for each entrypoint.
Initial vendor chunk
entry: {
vendor: ["react", "lodash", "angular", ...]
}
new CommonsChunkPlugin({
name: "vendors",
})
entry: {
vendor: ["react", "lodash", "angular", ...]
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: "initial",
test: "vendor",
name: "vendor",
enforce: true
}
}
}
}
Alternative:
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: "initial",
test: path.resolve(__dirname, "node_modules")
name: "vendor",
enforce: true
}
}
}
}
Difference: This includes all used modules from node_modules and allows tree shaking.
Note: You don't need to specify a entry for the alternative.
Commons chunk
new CommonsChunkPlugin({
name: "commons",
minChunks: 3
})
optimization: {
splitChunks: {
cacheGroups: {
commons: {
chunks: "initial",
minChunks: 3,
name: "commons",
enforce: true
}
}
}
}
Better vendor chunk
new CommonsChunkPlugin({
name: "vendors",
minChunks: module => {
return module.resource && /react|angluar|lodash/.test(module.resource);
}
})
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /react|angluar|lodash/
chunks: "initial",
name: "vendor",
enforce: true
}
}
}
}
Async commons chunk
new CommonsChunkPlugin({
async: true,
// ...
})
Just omit it. The defaults already do such optimization.
Deep Children
Anything with deepChildren: true
and no async
.
See configuration above but use chunks: "all"
.
Loaders consuming JSON
module.rules: [
{
test: /\.special\.json$/,
+ type: "javascript/auto",
use: "special-loader"
}
]
Activity
johnnyreilly commentedon Jan 22, 2018
Hey @sokra,
Just wanted to flag up that we're still hitting issues regarding when we're attempting to adding extra errors to the
compilation.errors
property inafter-compile
ints-loader
. Is there an alternate approach for registering errors with webpack that we could use instead?sokra commentedon Jan 22, 2018
hey @johnnyreilly
I have no clue about your issue.
errors
is a standard Array, without any special stuff. As long you pushing Errors into it it should work fine. Maybe you can open a separate issue, with a minimal loader repro repo.johnnyreilly commentedon Jan 22, 2018
Thanks @sokra - will do!
johnnyreilly commentedon Jan 22, 2018
@sokra I spent some more time digging into this; it looks like the trigger for making webpack hang is registering errors in the
after-compile
hook whenmode
has not been specified. Not quite sure why that happens.I'm going to go through our test pack and make sure that our configs are webpack 4 compliant.
HipsterZipster commentedon Jan 23, 2018
@sokra Amazing! Where can I find more information on sideEffects support? Will we be able to tree shake typescript transpiled code? See: mishoo/UglifyJS#1261
vladshcherbin commentedon Jan 23, 2018
@sokra Is it somehow possible to remove webpack
webpackBootstrap
code from bundle in webpack 4? Rollup produces far more cleaner output but doesn't have all plugins that webpack has.I've tried different config configurations,
concatenateModules
option, etc with no luck.michael-ciniawsky commentedon Jan 23, 2018
@vladshcherbin
webpack.config.js
vladshcherbin commentedon Jan 23, 2018
@michael-ciniawsky close, but it just extracts it into separate chunk which I don't need.
TheLarkInn commentedon Jan 23, 2018
@vladshcherbin it sounds like you are looking to suggest a library target feature? If so open a separate issue regarding this plz 🙇
drcmda commentedon Jan 23, 2018
It suddenly stopped working in production, anyone knows where my error is?
Relevant parts of webpack config
This only happens when
runtimeChunk: true
, if it'sfalse
, it runs through.index.template.ejs
Another thing i thought was odd,
mode: production
wires up uglify, env and so many other things, but it doesn't seem to minimize loaders by default, which i think maybe it should?I have to provide:
new webpack.LoaderOptionsPlugin({ minimize: true, debug: false })
, or else the bundle grows a couple of KB.20 remaining items