This article is reproduced with permission from Imprinted Chinese

HI, after Vue 3 and React 17, here I go again! Imprinted Chinese has completed the synchronization and translation work of Webpack V5 Chinese documents, you can read it seamlessly.

For details, see webpack.docschina.org. Webpack.docschina.org Important thing to say three times, our documents belong to the official, we do not have other domain name oh, and is real-time synchronization with the official. On October 10, 2020, WebPack was upgraded to version 5.0 and a blog directory was added to the official website. We have timely synchronization, this article is the summary of our version after reading. Without more words begin the text.

Since The Release of WebPack 4 in February 2018, there have been no further major updates to WebPack. In order to maintain API consistency, the old architecture has not changed much, leaving a lot of baggage. More than two years later, WebPack 5 was released on October 10, 2020, with a number of major changes that will greatly improve the efficiency and quality of front-end engineers’ builds.

The overall development direction of this major release is as follows:

  • Try using persistent caching to improve build performance.
  • Try to improve long-term caching with better algorithms and defaults.
  • Try to improve package sizes with better Tree Shaking and code generation.
  • Try to improve compatibility with web platforms.
  • To try to do this without introducing any disruptive changes,
    • Clean up internal constructs that were in a strange state when implementing V4 functionality.
  • Trying to prepare for future features by introducing breakthrough changes now,
    • Stay on version v5 for as long as possible.

The Release Note for WebPack 5 was quite long, so this article tries to extract the most concise information.

Function to remove

Clean up deprecated features

All features that were flagged as expiring in WebPack 4 have been removed in this release. So before migrating to WebPack 5, make sure your build running in WebPack 4 doesn’t have any feature expiration warnings.

Polyfills are no longer automatically referenced for Node.js modules

No longer add Polyfills automatically for Node.js built-in modules. Polyfills will be added automatically in WebPack 4 or earlier in any project that references node.js built-in modules. But webPack 5 will no longer do that, and webPack will put more effort into front-end module compatibility.

If you have modules that reference node.js in your code, upgrade to WebPack 5 by using front-end modules or manually adding the appropriate Polyfills.

For those library developers, define the Browser field in package.json to make the library available on the front end.

Optimization for long-term caching

The identified Chunk, module ID, and export name

New algorithms for long – term caching. These algorithms are enabled by default in production mode.

chunkIds: “deterministic”moduleIds: “deterministic”mangleExports: “deterministic”

The algorithm assigns short (3 – or 5-digit) numeric ids to modules and blocks in a deterministic manner, a tradeoff between package size and long-term caching. Since these configurations will use certain ids and names, this means that the generated cache invalidations are no longer more frequent.

The real content of the hash

When using *[contenthash]*, Webpack 5 will use the true file contenthash. Before, it only used the hash value of the internal structure. This can have a positive impact on long-term caching when only comments are modified or variables are renamed. These changes are not visible after compression.

Better development support

Named code block ID

In development mode, the new named code block ID algorithm enabled by default provides human-readable names for modules (and file names). The module ID is determined by its path, relative to context. The block ID is determined by the content of the block.

So you no longer need to use import(/ webpackChunkName: “name”/”module”) for debugging. But if you want to control filenames in your production environment, it makes sense.

You can use chunkIds in production: “named” in production, but make sure you don’t accidentally expose sensitive information about the module name.

Migration: If you don’t like changing file names during development, you can use the old digital mode via chunkIds: “Natural”.

Module federal

Webpack 5 adds a new feature, “module federation,” that allows multiple Webpack builds to work together. From a runtime perspective, multiple built modules will behave like one giant connected module diagram. From the developer’s point of view, modules can be imported from a specified remote build and used with minimal restrictions.

Support for new Web platform features

Some support for the Web platform has also been improved in Webpack 5.

JSON module

For JSON modules, for example, it will be the same as the current proposal and will require a default export, otherwise there will be a warning message. Even if using the default export, unused properties will also be optimization. UsedExports optimization, properties will be optimization. MangleExports optimization.

If you want to use a custom JSON parser, you can specify a custom JSON parser in rules.parser.parse to import JSON-like files (for tomL, YAML, JSON5, etc.).

Resource module

Webpack 5 now has built-in support for modules that represent resources. These modules can send a file to the output folder or inject a DataURI into a javascript package. Either way, they give you a URL to work with.

They can be used in a number of ways:

Import URL from “./image.png” and set type: “asset” in module.rule when matching such imports. (old method) new URL(“./image.png”, import.meta. URL) (new method) The “new method” syntax was chosen to allow code to run without a packaging tool. This syntax can also be used in native ECMAScript modules in browsers.

Native Worker support

When the resources of the new URL and new Worker/new SharedWorker/navigator serviceWorker. Combine the register, Webpack automatically creates a new entrypoint for the Web worker.

new Worker(new URL(“./worker.js”, import.meta.url))

This syntax was also chosen to allow the code to run without a packaging tool. This syntax is also available in the browser’s native ECMAScript module.

URIs

Webpack 5 supports handling protocols in requests.

  • supportdata:. Base64 or raw encoding is supported. Mimetype canmodule.ruleIs mapped to loader and module types. Such as:import x from “data:text/javascript,export default 42”
  • supportfile:
  • supporthttp(s):, but need to passnew webpack.experiments.s schemesHttp(s)UriPlugin()Opt in.
    • By default, when the target is “Web”, these URIs result in requests for external resources (they are external resources). Support for fragments in requests. Such as:./file.js#fragment

Asynchronous module

Webpack 5 supports so-called “asynchronous modules”. These modules are not resolved synchronously, but are based on asynchrony and Promise.

Importing them with “import “is handled automatically, requires no extra syntax, and is almost indistinguishable.

Importing them via require() returns a Promise resolved to the export.

In Webpack, there are several ways to have asynchronous modules.

  • Async externals
  • The WebAssembly module in the new specification
  • ECMAScript modules that use the top-level Await.

External resources

Webpack 5 adds more external types to cover more applications:

Promise: An expression that evaluates as a promise. The external module is an asynchronous module, and the parsed values are used as module exports.

Import. The native import() is used to load the specified request, and the external module is an asynchronous module that exports the parsed value as a module. An external module is an asynchronous module.

Module: not implemented, but planned to import x from “…” Load the module.

Script: Loads a URL through the script tag and takes the output from a global variable (and its optional attributes). An external module is an asynchronous module.

New node.js ecology features

Exports and imports fields in package.json are now supported. Yarn PnP is now supported natively.

See Package Exports for more details.

Improved development experience

Optimized build targets

Webpack 5 allows you to pass a list of targets, and supports versions of targets. For example, target: “node14” target: [“web”, “ES2020 “].

This is a simple way to give WebPack all the information it needs to determine:

  • Code block loading mechanism, as well
  • Supported syntax, such as arrow functions

statistical

Improved readability and redundancy of statistical test formats. Improved defaults to make them less verbose and suitable for large builds.

The progress of

The ProgressPlugin plug-in has also been optimized to count not only the progress of module compilation, but also entries and dependencies. Also, there are some performance optimizations that have been made in this upgrade, as the progress shown earlier may have some impact on build performance.

Automatically add unique names

In WebPack 4, multiple WebPack runtimes can conflict on the same HTML page because they use the same global variable for block loading. To solve this problem, you need to provide a custom name for the output.jsonpFunction configuration.

Webpack 5 does automatically infer a unique build name from package.json name and use it as the default for Output.uniquename.

This value is used to make all potentially conflicting global variables unique.

Migration: Since package.json has a unique name, you can remove output.jsonpFunction.

Automatically add a public path

Webpack 5 automatically determines output.publicPath when possible.

Typescript type

Webpack 5 generates typescript types from source and exposes them through NPM packages.

Migration: Remove @types/webpack. Update references when names are different.

Build optimization

Nested tree – shaking

Webpack is now able to track access to exported nested properties. This improves Tree Shaking (clearing unused exports and obfuscating exports) when reexporting namespace objects.

// inner.js
export const a = 1;
export const b = 2;

// module.js
export * as inner from './inner';
// import * as inner from './inner'; export { inner };

// user.js
import * as module from './module';
console.log(module.inner.a);
Copy the code

In this example, the exported B can be deleted in production mode.

Internal module tree-shaking

Webpack 4 does not analyze dependencies between module exports and references. Webpack 5 has a new option, optimization.innergraph, enabled by default in production mode, which analyzes flags in modules to find dependencies between exports and references.

In modules like this:

import { something } from './something';

function usingSomething() {
  return something;
}

export function test() {
  return usingSomething();
}
Copy the code

The internal dependency graph algorithm finds out that something will only be used if it is exported using test. This allows more exits to be marked as unused and more code to be omitted from the code package.

More modules can be omitted when *”sideEffects”: false is set. In this example, when the test export is not used,./something* is omitted.

To get unused export information, need to use optimization. UnusedExports. To remove modules that have no sideEffects, use optimization.sideeffects. The following tags can be analyzed:

  • Function declaration
  • Class declaration
  • Export default by defaultOr defining the following variables:
    • Functional expression
    • Such expressions
    • Sequential expression
    • / * #PURE* /expression
    • A local variable
    • Bindings for introduction

Feedback: If you find something missing from this analysis, please report a problem and we’ll consider adding it.

Using eval() gives up this optimization for a module, because code that has been eval can refer to any tag in scope. This optimization is also known as depth range analysis.

CommonJs Tree Shaking

Webpack used to do no export usage analysis on CommonJs exports and require() calls.

Webpack 5 adds support for some CommonJs constructs, allowing the elimination of unused CommonJs exports and tracing referenced export names from require() calls.

Supports the following constructs:

  • exports|this|module.exports.xxx = …
  • exports|this|module.exports = require(“…” ) (reexport)
  • exports|this|module.exports.xxx = require(“…” ).xxx (reexport)
  • Object.defineProperty(exports|this|module.exports, “xxx”, …)
  • require(“abc”).xxx
  • require(“abc”).xxx()
  • From ESM import
  • require()An ESM module
  • Marked export types (special treatment for non-strict ESM imports):
    • Object.defineProperty(exports|this|module.exports, “__esModule”, { value: true|!0 })
    • exports|this|module.exports.__esModule = true|! 0
  • Future plans support more constructs

When unparsable code is detected, WebPack gives up and does not track the export information for these modules at all (for performance reasons).

Consistency between development and production

We are trying to find a good balance between the build performance of the development pattern and avoiding the problems of only the production pattern by improving the similarities between the two patterns.

Webpack 5 has “sideEffects “optimizations enabled by default in both modes. In WebPack 4, due to incorrect “sideEffects” markup in package.json, this optimization resulted in some errors that only occur in production mode. Enabling this optimization during development makes it much faster and easier to find these problems.

In many cases, development and production takes place on different operating systems and file systems are case-sensitive, so WebPack 5 adds some strange case warnings/errors.

Improved Target configuration

In Webpack 4, “target “is a rough choice between” Web “and “node” (and a few others). Webpack 5 gives you more options. The target option now affects more things about generated code than before, such as how a code block is loaded, the format of the code block, whether externals is enabled by default, and so on.

In addition, for some of these cases, the choice between “Web” and “Node” is too sketchy, and we need more information. Therefore, we allow specifying the lowest version, such as “node10.13”, and infer more about the attributes of the target environment.

It is now also possible to combine multiple targets with an array, and WebPack will determine the minimum attributes for all targets. Using arrays is also useful when using targets like “Web” or “node” that do not provide complete information (no version number). For example, [“web”, “ES2020 “] combines these two part goals.

There is a target “Browserslist” that will use data from the Browserslist class library to determine the attributes of the environment. This target is also used by default when a Browserslist configuration is available in the project. When no configuration is available, the “Web” target is used by default.

Code block split and module size

Now the size of the module is a better way to express it than a single number. Now there are different types of sizes.

SplitChunksPlugin now knows how to handle these different sizes and use them for minSize and maxSize. By default, only javascript sizes are processed, but you can now pass multiple values to manage them:

module.exports = {
  optimization: {
    splitChunks: {
      minSize: {
        javascript: 30000.webassembly: 50000,},},},};Copy the code

You can still use a number for size. In this case, WebPack automatically uses the default size type.

The mini-CSS-extract-Plugin uses CSS /mini-extra as the size type and automatically adds this size type to the default type.

There are other build optimizations, such as individual runtime improvements, module consolidation, generic Tree Shaking improvements, and individual generated code improvements. See the WebPack 5 release for details.

Performance optimization

The persistent cache

There is now a file system cache. It is optional and can be enabled with the following configuration:

module.exports = {
  cache: {
    // 1. Set the cache type to file system
    type: 'filesystem'.buildDependencies: {
      // 2. Add your config as buildDependency to get cache invalidation when changing config
      config: [__filename],

      // 3. If you have other things to build on, you can add them here
      // Note that webpack, loader, and all modules referenced from your configuration are automatically added,}}};Copy the code

Important Note:

By default, Webpack assumes that the node_modules directory in which webpack resides is only modified by the package manager. For node_modules, hashes and timestamps are skipped. For performance reasons, only the package name and version are used. Symlinks(that is, NPM/YARN Link) is fine (to be avoided at all costs) as long as resolve. Symlinks: false is not specified. Do not edit the files in node_modules directly, unless you use snapshot.managedPaths: [] to remove the optimization. When using Yarn PnP, Webpack assumes that the Yarn cache is immutable (it usually is). You can exit this optimization using snapshot.immutablePaths: [].

Cache will be stored by default in node_modules/.cache/webpack (when node_modules is used) or.yarn/.cache/webpack (when yarn PnP is used). When all plug-ins handle caching correctly, you probably never need to manually remove it.

Many internal plug-ins also use persistence caching. Examples include SourceMapDevToolPlugin (cache SourceMap generation) or ProgressPlugin (cache module number)

The persistent cache automatically creates multiple cache files based on usage to optimize read and write access to the cache.

By default, timestamps are used for snapshots in development mode and file hashes are used for production mode. File hashing also allows the use of persistent caching in CI.

The compiler is idle and closed

The compiler now needs to be closed after use. The compiler now enters and leaves idle states and has hooks for those states. Plug-ins may use these hooks to do unimportant work. The persistent cache slowly stores the cache to disk. When the compiler shuts down – all remaining work should be done as quickly as possible. A callback signals completion of the shutdown.

Plug-ins and their respective authors should anticipate that some users may forget to close the compiler. Therefore, all work should eventually be done in the idle state. You should prevent the process from exiting while work is in progress.

The Webpack () usage automatically calls close when a callback is passed.

Migration: When using the Node.js API, be sure to call Compiler.close when you have finished your work.

Files are generated

Webpack used to always ship out all the output files on the first build, but skipped writing unchanged files on incremental (watch) builds. Assume that nothing else changes the output file while WebPack is running.

After adding persistent caching, you should have a listening-like experience even when you restart the Webpack process, but it’s too strong to assume that nothing else changes the output directory even when WebPack isn’t running.

So WebPack now examines the existing files in the output directory and compares their contents to the output files in memory. It writes to the file only when the file is changed. This only happens on the first build. Any incremental build is written to the file as new assets are generated in the running WebPack process.

We assume that WebPack and plug-ins generate new assets only when the content is changed. You should use caching to ensure that no new assets are generated while the input is the same. Failure to follow this advice can degrade performance.

Files marked immutable (including content hashes) will never be written if a file with the same name already exists. We assume that the content hash changes when the content of the file changes. This is generally true, but may not always be true during Webpack or plug-in development.

Major changes: Long unresolved issues

Code segmentation for a single file object

Targets that only allow the launch of a single file (such as Node, WebWorker, electron Main) now support runtime auto-loading of dependent code snippets required for boot.

This allows the use of these goals chunks: “all” and optimization runtimeChunk.

Note that if the target’s code block load is asynchronous, this makes the initial evaluation asynchronous as well. This can be a problem when using output.library, because the exported value is now a Promise.

The parser has been updated

Enhanced – Resolve was updated to V5 with the following improvements:

  • Track more dependencies, such as missing files.
  • Aliases may have several choices
  • It can now be alias tofalse.
  • supportexportsimportsFields and other functions.
  • Performance improvement

No JS code block

Blocks that do not contain JS code will no longer generate JS files. This allows for a block of code that contains only CSS.

Major changes: Future plans

The experimental features

In WebPack 5, there is a new Experiments configuration option that allows experimental functionality to be enabled. This makes it clear which features are enabled/used.

Although WebPack follows semantic versioning, it makes exceptions for experimental features. Experimental features can include disruptive changes in minor versions of Webpack. When this happens, we add an explicit comment to the change log. This will allow us to iterate on experimental features faster, while also allowing us to stay with stable features longer on major releases.

The following experimental features will ship with WebPack 5.

  • Old WebAssembly support, just like WebPack 4 (experiments.syncWebAssembly )
  • According to the updated specification (experiments.asyncWebAssembly), added WebAssembly support.
    • This makes a WebAssembly module an asynchronous module.
  • Top-level Await phase 3 proposal (experiments.topLevelAwait )
    • Use at the top levelawaitMake the module an asynchronous module.
  • Generate code packages as modules (experiments.outputModule )
    • This removes the wrapper IIFE from the code package, enforcing strict mode through
    <script type="module">
    Copy the code

    Lazy loading with minimal compression in module mode.

Note that this also means that WebAssembly support is now disabled by default.

Minimum Node.js version

The minimum supported node.js version was increased from 6 to 10.13.0(LTS).

Migration: Upgrade to the latest node.js version.

Major internal architecture changes

This section is mainly for those who want to contribute to the WebPack kernel, as well as loaders and plug-in developers to pay close attention to. If you just use Webpack, you can ignore this section. It’s very informative and difficult to understand.

Let’s take a look at some of the major internal architectural changes.

New plug-in running order

Plug-ins in WebPack 5 will now be applied before applying the configured default values. This allows the plug-in to apply its own defaults or as configuration presets. But this is also a radical change, because plug-ins cannot rely on configuration values when applied.

Migration: Access configuration only in plug-in hooks. Or better yet, avoid the configuration altogether and get the options through the constructor.

Runtime module

Most of the runtime code is moved into what are called “runtime modules”. These special modules are responsible for adding runtime code. They can be added to any block, but are currently always added to the runtime block. Runtime requirements control which runtime modules (or core runtime parts) are added to the code package. This ensures that only used run-time code is added to the code package. In the future, runtime modules can also be added to blocks loaded on demand to load runtime code when needed.

In most cases, the core allows the entry module to be inlined when running the code, rather than calling it with webpack_require. If there are no other modules in the code package, there is no need to use webpack_require at all. This combines well with module merging, where multiple modules are merged into a single module. In the best case, no runtime code is required at all.

Migration: If you inject runtime code into the WebPack runtime from plug-ins, consider using RuntimeModules instead.

serialization

We added a serialization mechanism to allow serialization of complex objects in Webpack. It has an optional semantics, so those classes that should be serialized need to be explicitly marked (and their serialization implemented). Most modules, all dependencies, and some errors already do this.

Migration: When using custom modules or dependencies, it is recommended that they be serializable to benefit from persistent caching.

A plug-in for caching

Added a Cache class with a plug-in interface. This class can be used for both write and read caches. Depending on the configuration, different plug-ins can add functionality to the cache. MemoryCachePlugin adds memory caching capabilities. FileCachePlugin adds persistence (file system) caching. FileCachePlugin uses a serialization mechanism to persist cached items to and from disk.

Tapable plugin upgrade

The Compat layer of the WebPack 3 plug-in has been removed. It has been removed from WebPack 4. Some lesser-used Tapable apis were removed or deprecated.

Migration: Use the new Tapable API.

The Main/the Chunk/ModuleTemplate abandoned

The packaging template has been refactored. MainTemplate ChunkTemplate/ModuleTemplate abandoned, now JavascriptModulesPlugin responsible for JS template.

Prior to that refactoring, the JS output was handled by Main/ChunkTemplate, while the other output (i.e., WASM, CSS) was handled by the plug-in. This makes it seem that JS is a first-class citizen and other outputs are second-class. Refactoring changes this, and all output is handled by their plug-in.

You can still hack into some templates. The hook is now in the JavascriptModulesPlugin instead of the Main/ChunkTemplate. (Yes, plug-ins can also have hooks, which I call add-on hooks.) A compatibility layer, so the Main Chunk/ModuleTemplate still exist, but only entrust the tap call new hook position.

Migrate: As recommended in the Deprecation message. It’s basically hooks that point to different places.

New configuration of import file

In WebPack 5, entry files can also be configured with descriptors in addition to strings and string arrays, such as:

module.exports = {
  entry: {
    catalog: {
      import: './catalog.js',}}};Copy the code

It is also possible to define the filename of the output, which was previously defined by output.filename:

module.exports = {
  entry: {
    about: { import: './about.js'.filename: 'pages/[name][ext]',}}};Copy the code

In addition, the configuration of entry files has added file dependency definitions, the format type of the generated library (CommonJS or AMD), the name of the runtime, and the way the code block is loaded. For more details, refer to the complete release record.

The sort and ID

Webpack used to sort modules and code blocks in a specific way at compile time, assigning ids incrementally. That’s no longer the case. Order is no longer used for ID generation; instead, full control of ID generation is in the plug-in. The hooks that optimize the order of modules and code blocks have been removed.

Migration: At compile time, you can no longer rely on the order of modules and code blocks.

From array to Set

  • Compiler.modules is now a collection
  • Compilation.chunks is now a collection
  • Chunk.files is now a collection

There is an adaptation layer but it prints a deprecation warning.

Migration: Use collection methods instead of array methods.

File system and information changes

Webpack 5, one is the need to use the Compilation, replace the file/contextTimestamps fileSystemInfo, get the timestamp of the file information, Another is the addition of Compiler.modifiedFiles to make it easier to reference the changed files.

In addition, also added a similar to the compiler. InputFileSystem and compiler. The compiler outputFileSystem new API. IntermediateFileSystem, For all FS operations that are not considered input or output, such as writing records, caching, or output profiling.

Module hot replacement

The HMR runtime has been refactored as a runtime module. The HotUpdateChunkTemplate has been merged into the ChunkTemplate. ChunkTemplates and plugins should also handle HotUpdateChunk.

The javascript portion of the HMR runtime has been separated from the core HMR runtime clock. Other module types can now also handle HMR in their own way. In the future, this will allow HMR to handle modules such as mini-CSS-extract-Plugin or WASM.

Migration: This is a new feature and no migration is required.

Import.meta. WebpackHot exposes the same API as module.hot. It can of course be used in ESM modules (.mjs, type: “module” in package.json) that do not have access to modules.

The work queue

Webpack used to do module processing in the form of function calls, and there was a Semaphore option to limit parallelism. Compilation. Semaphore has been removed and can now be processed using asynchronous queues, with separate queues for each step:

  • Compilation.factorizeQueue: calls the module factory for a set of Dependencies.
  • Compilation.addModuleQueue: Adds modules to the build queue (you can use cache recovery modules)
  • Compilation.buildQueue: Build modules if necessary (modules can be stored in the cache)
  • Compilation.rebuildQueue: If manually triggered, the module will be rebuilt
  • Compilation.processDependenciesQueue: Handles dependencies of the module.

These queues have hooks that listen for and intercept working processes. In the future, multiple compilers will work at the same time, and you can orchestrate compilation work by intercepting these queues.

Migration: This is a new feature and no migration is required.

Module and Chunk diagram

Webpack used to store parsed modules in dependencies and imported modules in chunks. But that has changed. All information about how modules are connected in the module diagram is now stored in the ModulGraph’s class. All information about how the module connects to the chunk is now stored in ChunkGraph’s class. The chunk-dependent information is also stored in the relevant class.

Here are some examples of modules whose information has been moved:

  • Module connections -> ModuleGraph
  • Module issuer -> ModuleGraph
  • Module optimization bailout -> ModuleGraph (TODO: check if it should ChunkGraph instead)

When a module is recovered from the cache, Webpack interrupts the module from the diagram. This is no longer necessary. A module does not store any information about a graph and can technically be used in multiple graphs. This makes caching much easier. Most of these changes have an adaptation layer that prints a deprecation warning when used.

Migration: Use the new API on ModuleGraph and ChunkGraph.

Module Source Types

Modules must now define the source types they support with module.getSourceTypes (). Depending on this, different plug-ins call source() with these types. For JavascriptModulesPlugin whose source type is javascript, the source code is embedded in the bundle. The WebAssemblyModulesPlugin of the source type WebAssembly emits a WASM file. Custom source types are also supported. For example, the Mini-CSS-extract-Plugin inserts source code into CSS files using the source type stylesheet.

There is no relationship between module types and source types. Javascript and WebAssembly of source type javascript and module type WebAssembly /experimental can be used, even if the module type is JSON.

Migration: Custom modules need to implement these new interface methods.

A brand new observer

The observer used by Webpack has been refactored. It previously used Chokidar and native dependencies fsevents (only on OSX). It is now in FS based only on native Node.js. This means there are no native dependencies left in Webpack.

It also captures more information about the file system as it listens. Currently, it can also capture mtimes and monitor event times, as well as information about missing files. To do this, the WatchFileSystem API has made a small change. We also convert the Arrays to Sets and Objects to Maps.

SizeOnlySource after emit

Webpack now replaces Sources in Compiler. assets with SizeOnlySource to reduce memory footprint.

ExportsInfo

The storage mode of module export information is reconstructed. ModuleGraph now provides an ExportsInfo for each Module, which is used to store information for each export. If the module is used only as a side effect, it also stores information about unknown exports,

For each export, the following information is stored:

  • Do you want to use export? Use is uncertain. (seeoptimization.usedExports)
  • Is export provided? There is no certainty of availability. (seeoptimization.providedExports)
  • Can you rename export? I’m not sure if I want to rename it
  • If export has been renamed, it is the new name. (seeoptimization.mangleExports)
  • Nested ExportsInfo, export is itself an object if it is an object with additional information
    • Used to re-export namespace objects:import * as X from “…” ; export { X } ;
    • Used to represent the structure in a JSON module

Code generation phase

Compiled code generation functions as a separate compilation phase. It is no longer hidden in the Module. The source () and the Module getRuntimeRequirements run (). This should make the process simpler. It also runs to report progress for that phase. And make code generation more visible when dissected.

Migration: the Module. The source (), and the Module. The getRuntimeRequirements () has been deprecated. Use * module.codegeneration () instead.

Dependency reference

Webpack has a single method and type to represent the dependence of reference (Compilation. GetDependencyReference returns a DependencyReference) this type is used to introduce all the information about the reference, For example, what exports have been introduced into the referenced module? If it is a weak reference, some relevant information needs to be subscribed. Building all this information together, getting a reference is expensive and frequent (every time someone needs an information).

In webpack5, this part of the code base was refactored and the methods split.

  • The referenced module can be read from the ModuleGraphConnection
  • The name of the imported exportDependency.getReferencedExports()To obtain
  • DependencyClass will have oneweakThe flag of
  • Sorting and onlyHarmonyImportDependenciesRelated, can passsourceOrderProperties for

Presentational Dependencies

This is a new class of Dependencies for NormalModules: Presentational Dependencies

These dependencies are used only during code generation, but not during module diagram building. So they can never reference modules or affect exports/imports.

These dependencies are cheap to handle, and WebPack uses them wherever possible

Deprecated loaders

Null-loader is deprecated. use

module.exports = {
  resolve: {
    alias: {
      xyz$: false,}}};Copy the code

Or use an absolute path

module.exports = {
  resolve: {
    alias: {
      [path.resolve(__dirname, '....')]: false,}}};Copy the code

conclusion

Most of the work in WebPack 5 revolves around optimization, removing the deprecated content from 4, adding long-term caching, optimizing the kernel, and so on. This article just picks the key points for you to explain, specific changes please refer to the official document.

Chinese version: webapck.docschina.org

** More exciting content, please pay attention to Tencent VTeam technical team wechat public account and video number **