1
头图

Original address

Write loader and plugins

github

One, loader

1.loader introduction

What is loader

Loader is actually a function that converts the matched content and returns the converted result.

Loader role

In webpack , loader like a translator. webpack only recognizes the JavaScript . For other resources, they can be converted and preprocessed after loader
  • The execution of loader is sequential, supports chained calls. The execution order of the loader is from bottom to top, from right to left. For example, processing style files, use:['style-loader', 'css-loader'] . css-loader processed file by style-loader returned to 060bf31a186854.
  • The responsibility of a Loader is single, and only one conversion needs to be completed.
  • Webpack will cache the processing results of all Loaders by default, and will not reload the unmodified loaders. To turn off the default cache results of webpack, you need to add this.cacheable(false);

Common loaders

  • Style loader: css-loader, style-loader, less-loader, postcss-loader (add-webkit), etc.
  • File loader: url-loader, file-loader, raw-loader etc.
  • Compiled loader: babel-loader, ts-loader etc.
  • Check test type loader: eslint-loader, jslint-loader etc.

4. Three ways to use loader

    1. Configure in webpack.config.js

      module.exports = {
        module:{
         rules:[{
                 test:/\.css$/,
                 use:['css-loader'],
                 // use:{loader:'css-loader',options:{}}
             }
         ]
        }
      }
    1. Parameters via the command line

      webpack --module-bind 'css=css-loader'
    1. Use inline

      import txt from 'css-loader!./file.css';

2. Write a loader

Idea: We said earlier that 1.loader is a function; 2. Convert the matched content; 3. Then return the converted content. According to this idea, we can write the simplest loader
// 在 ./loader/replaceLoader.js 创建一个替换字符串的 loader
module.exports = function(source) {
    return source.replace('a', 'b')
}

// 在webpack.config.js 使用 自己写的loader
module.exports = {
    module:{
        rules:[{
            test:"/\.js$/",
            use:[{
                    loader: path.resolve(__dirname, './loader/replaceLoader.js')
                    options:{
                        name: '林一一'   
                    }
                }
            ]
        }]
    }
}

// 或者使用 replaceLoader
module.exports={
    resolveLoader:['node_modules', './loader']
    module:{
        rules:[{
            test:"/\.js$/",
            use:['resolveLoader']
        }]
    }
}
The above is the simplest case of writing a loader
  • loader can also receive options incoming parameters, see the details loader API , you can also use the official provided loader-util receive parameters

    const loaderUtil = require('loader-utils')
    module.exports = function(source) {
      console.log(this.query.name) // 林一一
      const options = loaderUtil.getOptions(this)
      return source.replace('a', 'b')
    }
  • Asynchronous: Loader is a function, naturally there is a distinction between synchronous and asynchronous. To use asynchronous loader, you need to add this.async() declare asynchronous operation

    const loaderUtils = require('loader-utils')
    module.exports = function(source) {
      const options = loaderUtils.getOptions(this)
      const callback = this.async()
      setTimeout(()=>{
          console.log(options.name)
          let res = source.replace('a', options.name)
          callback(null, res, sourceMaps, ast)
      }, 4000)
    }
    The above code will be packaged successfully after 4 seconds. If there is no this.async() asynchronous operation, it will fail, and the callback() callback function will put the result back.
  • By default, the string encoding passed by webpack to the loader is utf-8 . If you need to process binary files, you need to add exports.raw = true .
  • As mentioned above, webpack will cache the loading result of loader by default. If you need to close the cache result of webpack this.cacheable(false); .
  • Npm link specifically used to develop and debug local Npm modules. If it is not released to npm, it can also be used to debug local loader . Specific needs package.json configuration local loader, performed in the root directory npm link loader-name can in node_modules use in local loader a. At the same time, you can also use the above resolveLoader realize the import loader method

Summarize the idea of writing loader

  1. Loader is an export function with a return value, which can be implemented with the help of third-party modules and Node api.
  2. Loader can use loader-utils receive the parameters passed options
  3. The asynchronous writing of the loader needs to display the declaration const callback = this.async() indicating asynchronous.
  4. exports.raw = true if it needs to process binary files
  5. loader allows the results to be webpack cache, if you need to close webpack cache results need to declare this.cacheable(false)
  6. The written local loader can be imported with the help of Npm link or resolveLoader

Second, the construction process of webpack

Before talking about plugins, you need to know what the webpack build process is like.
  1. initialization parameters. Parameters merged from the configuration file and shell
  2. began to compile. Initialize the parameters obtained in the previous step into a object, load all imported plug-ins, and execute the run method of the object to start compiling;
  3. determines the entrance. Find all the entry files from the configured entry
  4. compile the module. According to the dependency of the entry file, call all configured loader for conversion.
  5. completes the module compilation and output. According to the dependency between the entry files, a code block chunk .
  6. output is complete. Output the formed code block chunk to the file system.
complier object initialized above will be injected into the apply(complier) of the plug-in. complier object contains all the configuration information of the Webpack environment, such as options, loaders, plugins and other attributes. You can simply think that complier is an instance of compler.plugin() you can listen to the webpack broadcast by 060bf31a191c49 through 060bf31a191c47.

Three, plugin

1 plugin introduction

what is plugin

plugin is a plug-in, this plug-in is also a class, implemented based on the event flow framework Tapable . In the webpack build process, after initializing the parameters, all plugin plug-ins will be loaded and an instance of the plug-in will be created.

plugin function

plugin can relate to by hook webpack whole event process. In other words, plugin can use the API provided by webpack to do something at the right time by monitoring these life cycle hooks.

Common plugin

  • html-webpack-plugin will automatically generate a html file after packaging, and will import the packaged js file into the html file.
  • optimize-css-assets-webpack-plugin compresses the CSS code.
  • mini-css-extract-plugin . style the css written in the 060bf31a191ef9 tag into a CSS file generated by importing link
  • webpack-parallel-uglify-plugin . Enable multi-process execution code compression to improve the speed of packaging.
  • clean-webpack-plugin . Delete the old generated files each time before packaging.
  • serviceworker-webpack-plugin . Add offline caching function for web applications.

How to use plugin

plugins in 060bf31a192279
const ServiceworkerWebpackPlugin = require('serviceworker-webpack-plugin')
module.exports = {
    plugins:[
        new ServiceworkerWebpackPlugin(),
    ]
}

2 Write a plugin

Idea: plugins is a class, webpack provides a lot of built-in api apply(compliers) function needs to be defined on the prototype. At the same time, specify the webpack hook to be mounted.
class MyPlugin {
    constructor(params){
        console.log(params)
    }
    // webpack 初始化参数后会调用这个引用函数,闯入初始化的 complier对象。
    apply(complier){
         // 绑定钩子事件
        // complier.hooks.emit.tapAsync()
        compiler.plugin('emit', compilation => {
            console.log('MyPlugin')
        ))
    }
}
module.export = MyPlugin
compilation object contains the current module resources, compiled resources, and files that can monitor changes. After each change in a file, will generate a compilation object, compilation can be read to compiler object.
Modal plugin may be used in the node tone tool package.json added in "debug":"node --inspect --inspect brk node_modules/webpack/bin/webpack.js"

Summarize the idea of writing plugin

  1. Write a class class.
  2. Define an apply method in the class.
  3. In the application of the method apply() specified mount in webpack event hook complier.hooks. .
  4. Process specific data of the internal instance of webpack.
  5. Call the callback provided by webpack after the function is completed.

Four, interview questions

1. The difference between loader and plugin

  1. Loader is a function used to match and process a specific module, convert the received content and return it. Operate files in webpack and act as a file converter. Configured in modules.rules
  2. plugin is a plugin does not directly manipulate files, event-based workflow framework Tapable implemented, plugin may involve by hook webpack whole of a flow of events. In other words, plugin can use the API provided by webpack at the right time to do something by monitoring these life cycle hooks. Configure the plugin in plugins

2. The idea of writing loader

Participate

3. The idea of writing plugin

Participate

4. The difference between complier and compilation

  1. The complier object exposes hooks related to the entire life cycle of webpack . It is the product of the parameters initialized by options, entry, plugins . The attributes including 060bf31a192a29 can be simply understood as an instance webpack
  2. compilation object is complier , and it is the life cycle object during the construction webpack After each file changes, a complition object can be generated.
    Summary: Both objects have their own life cycle hooks. The compilation object is responsible for life cycle hooks with a smaller granularity. compiler object is the whole life cycle hook object of webpack.

reference

loader and plugin of

webpack build process

webpack loader and plugin writing

in-depth Webpack-writing Loader


林一一
171 声望7 粉丝