What does Webpack do?

  • Module packaging
    • According to the dependencies of the dependency diagram, the files of different modules are packaged together, and the references between them are correct, and the execution is orderly.
  • Compile the compatible
    • The webpackloaderMechanisms can compile transformations.less, .vue, .jsxSuch as browser can not recognize the format of the file, improve development efficiency
  • Ability to expand
    • The webpackPluginOn the basis of modular packaging and compiler compatibility, load on demand is extended to solve other things that loader cannot implement, such as actual listening, etc.

A few key concepts for Webpack

  • Entry: Entry files, which can be one or more Entry files, indicate which modules WebPack should use as a starting point for building dependency diagrams
  • Output: output file that tells WebPack where to print what it has createdbundleAnd how do you name these files
  • Loaders: Loaders, essentially functions that receive resource files for conversion and return new files
  • Plugins: Plugins, extensions, event listening, etc
  • Mode: mode by selectiondevelopment.production 或 noneOne of them, to set up the environment

Modular packaged running processes?

Q: How does WebPack put these modules together and make them work? First you need to understand the webPack packaging process:

  • Initialization parameter
    • readwebpackConfiguration parameters of;
  • Begin to compile
    • Start thewebpackTo createCompilerObject and startparsingThe project;
  • Determine the entrance
    • Slave fileentryStart parsing, build the dependency graph of its import file, recursive analysis to form a dependency tree;
  • Compiling templates
    • Use corresponding for dependent module files of different file typesLoaderCompile, and finally convertJavascriptFile;
  • Complete template compilation and output
    • According to the dependencies between the entry files, a code block is formedchunk, will form a code blockchunkOutput to the file system

Note: In the whole packaging process, the plugin listens to the event node and performs the plug-in task to achieve the purpose of intervening the output result.

In Webpack source code, file parsing and construction mainly rely on compiler and Compilation two core object implementation.

The dependencies between each module depend on the AST syntax tree, through which the module can be analyzed whether there are other dependent modules, and then continue to cycle the compilation and parsing of the next module. The final bundle packaged by Webpack is an IIFE execution function.

Complier is different from compilation

The Compiler object is a global singleton that controls the entire WebPack build process. Complier objects expose the entire webPack lifecycle of the hook, is the product of webPack initialization parameters, including options, entry, plugins and other properties can be easily understood as an instance of WebPack.

The compilation object is a context object for each build, an instance of Complier, and a life cycle object for each WebPack build. It contains all the information needed for the build, and with each hot update and rebuild, compiler regenerates a new compilation object that takes care of the build process for the update. Summary: Both objects have their own lifecycle hooks. Compiler objects are objects for the entire Webpack lifecycle hooks from start to close. The compilation object is responsible for smaller-grained lifecycle hooks that simply represent a new compilation.

Have you written Loader? How to write loader?

Loader configuration information

Loader in webpack is a function that converts the matched content and returns the converted result. It can be seen from the configuration that Loader supports multiple configurations in the form of arrays. Loader supports chained invocation, which is executed from bottom to top and from right to left. In order to ensure the normal operation of loader, the development needs to follow some specifications, for example, the return value must be the standard JS code string; Follow the “single responsibility “(that is, a Loader only needs to perform one transformation) and only care about the output of the Loader and its corresponding output.

module.exports = {
  module: {
    rules: [{test: /.css$/, use:['style-loader'.'css-loader']},// From right to left, the file processed by 'css-loader' is returned to the file processed by 'style-loader'
      { test: /.ts$/, use: 'ts-loader'},],}};Copy the code

To summarize the idea of writing loader:

The essence of Loader is a function, and the this context of loader function is provided by Webpack. Therefore, we cannot set Loader as an arrow function. We can obtain various information data required by the current Loader through the relevant properties provided by this object. The job of the loader function is to get the original content before processing, perform processing on the original content, return the processed content. See the reference documentation for details: Webpack Principles – Writing loaders and Plugins

Common loader

  • Loader for style classes:css-loader, style-loader, less-loaderEtc.
  • Loader for file classes:url-loader, file-loaderAnd so on.
  • Loader to compile classes:babel-loader, ts-loaderEtc.
  • Check test class loader:eslint-loader, jslint-loaderEtc.

Have you written a Plugin? What is the idea of writing a Plugin?

Plugin configuration information

Plugins are classes, and WebPack provides plugins with a number of built-in apis. During the life cycle of WebPack, plugins broadcast many events, and plugins can listen for these events and change the output results when appropriate through the API provided by WebPack. The Apply (compliers) function needs to be defined on the prototype. Also specify the Webpack hook to mount.

The basic Plugin code looks like this:

class MyPlugin {
    // Get the configuration passed in by the user to the plug-in in the constructor
    constructor(params){}// WebPack will call the apply method of MyPlugin instance after initializing the parameter, passing the plugin a Complier object.
    apply(complier){
         // Bind the hook event
        // complier.hooks.emit.tapAsync()
        compiler.plugin('emit'.compilation= >{})}}module.export = MyPlugin  / / export Plugin
Copy the code

When using this Plugin, the configuration code is as follows:

const MyPlugin = require('./MyPlugin.js');
module.export = {
  plugins:[
    new MyPlugin(options),
  ]
}
Copy the code

After Webpack is started, a new MyPlugin(options) is executed to initialize a MyPlugin instance during the configuration reading process. After initializing the Compiler object, the instance method myPlugin.apply(Compiler) is called to pass the compiler object to the plug-in instance. Once the compiler object is acquired, the plug-in instance can listen for events broadcast by Webpack through compiler.plugin(event name, callback function). The Compiler object can also be used to manipulate Webpack.

Summarize the idea of writing Plugin:

  1. Write aJavaScriptNamed functions.
  2. Define one on its prototypeapplyMethods.
  3. In application methodapply()Specified inwebpackEvent hookscomplier.hooks..
  4. To deal withwebpackSpecific data for the internal instance.
  5. Called when the function completeswebpackThe callback provided.

Common Plugin

  • html-webpack-pluginOne will be generated automatically after packaginghtmlFile, and will introduce the packaged JS file tohtmlWithin the file.
  • optimize-css-assets-webpack-pluginCompress the CSS code.
  • mini-css-extract-plugin. Will writestyleThe CSS inside the tag is separated into onelinkImport the generated CSS file
  • webpack-parallel-uglify-plugin. Enable multi-process execution code compression, improve packaging speed.
  • clean-webpack-plugin. Delete old generated files before each package.
  • serviceworker-webpack-plugin. Add offline caching for web applications.

What is the difference between Loader and Plugin?

  • loderIs a file loader, can load resource files, and perform some processing on these files, such as compilation, compression, etc.Run before packaging the file, and finally package the resources into the specified file
  • pluginGive WebPack more flexible functions, such as package optimization, resource management, environment variable injection, etc., the purpose is to solve and extendloderOther features that are not available,This works throughout the compile cycle

The entire runtime of Webpack is shown below:

A number of events are broadcast during the life cycle of a Webpack run, and the Plugin can listen for these events and change the output when appropriate through the API provided by Webpack.

For Loader, it is essentially A converter. It compiles A file into B file and operates the file. For example, it converts A.CSS or A.less into B.CSS.

Reference documentation: Difference between Loader and Plugin

Talk about Webpack versus Babel

webpack

Webpack is a modular packaging tool, packaging JS files, CSS files, images, HTML and so on, it can analyze the file structure of the entire project, confirm the dependencies between files, such as one JS file introduced another JS file. In this process, js can be synthesized, compressed, and finally generated project files.

babel

Babel is a JS compiler that converts the latest JS syntax into ES5 syntax and runs in most browsers. Arrow functions like ES6 do the conversion. The implementation of Babel consisted of three steps: parsing, transformation, and finally code generation.

// Babel input: ES2015 arrow function
[1.2.3].map((n) = > n + 1); 
// Babel output: the same functionality as the ES5 syntax
[1.2.3].map(function(n) { return n + 1; });
Copy the code

While Babel only converts syntax, some of the newer apis don’t, such as Object.assign, Promise, etc. So Babel also provides a lot of plug-ins, called Babel-Pilofill. After installation, you can support the browser to run. Babel-pilofill is based on core-JS and ReGenerator. Pilofill, however, introduces full API support. If you use only part of the API, you can introduce only the corresponding modules.

Babel can also convert JSX syntax and React support is better. Babel presents, presents is a collection of plugins. Babel generally needs to work with Webpack to compile module syntax. How to configure Babel in webpack?

Plugins are run first.

{"plugins": ["transform-decorators-legacy", // run "transform-class-properties" // run again]}Copy the code

But presents is presented first and executed later, for better compatibility.

{"presets": ["es2015", // es2015" react", "stage-2", // stage-2]}Copy the code

Webpack hot update

Hmr-hot Module Replacement is one of the most useful features webPack provides. Hot replacement refers to the replacement, addition, deletion of modules without the need to refresh and reload the page. If HMR is not configured, you need to refresh the page every time you change the interface to see the changed result. This is very troublesome and inefficient for debugging. The most important thing is that the data you modify on the interface will be lost as the page is refreshed. However, Webpack hot update mechanism exists, even if the code is modified, it will not cause the refresh, but retain the existing data state, only the module is updated and replaced. That is, the existing data state is preserved and the code changes are visible.

Its ideas mainly include the following aspects:

  • Save the application state when the page loads
  • Update only the changed content, saving development and debugging time
  • Changing styles is faster, almost the same as changing styles in a browser

A webpack.config.js file with hot replacement is configured as follows to do several things

  1. The WebPack library was introduced and dependencies were installed$ npm install webpack webpack-dev-server --save-dev
  2. configurationdevServer, among the optionshotField istrue, indicating that hot update is enabled
    DevServer: {contentBase: path.resolve(__dirname, 'dist'), hot: true, compress: true //Copy the code
  3. usenew webpack.HotModuleReplacementPlugin()
    plugins: {
        HotModuleReplacementPlugin: new webpack.HotModuleReplacementPlugin()
    },
    Copy the code

How does Webpack implement hot updates?