笔记-webpack

126 阅读2分钟

webpack 是一个打包工具,目的就是把有依赖关系的各种文件打包成一系列的静态资源

webpack有一个配置文件,核心内容:

  • entry:入口文件
  • output:出口 webpack处理完成后文件存放位置
  • loader:模块转换器,将模块原内容转换成新内容,
  • 插件:在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果

webpack配置

1.初始化项目

新建webpack-demo目录

npm init -y

安装 webpack和webpack-cli

npm install webpack webpack-cli --save-dev

新建/src/index.js

class Person{
    constructor(name){
        this.name = name;
    }
    sayName(){
        console.log('my name is'+this.name);
    }
}
const tom = new Person('tom');

从 wepack4 开始, webpack 在不引入任何配置文件的情况下就可以使用。 使用 npx webpack --mode=development打包,默认模式为production,使用development模式方便查看打包后的代码 执行完成项目目录下生成dist目录,里面有一个main.js文件。 webpack 有默认配置,默认的入口文件是 ./src,默认打包到dist/main.jsdist/main.js中,src/index.js还是es6代码,没有转换es5

2.模式(mode)

mode可选参数有evelopment,productionnone,用来启用 webpack 内置在相应环境下的优化。其默认值为 production。

  • evelopment:将 process.env.NODE_ENV 的值设置为 development,启用 NamedChunksPluginNamedModulesPlugin 添加modewebpack.config.js
  • production:将 process.env.NODE_ENV 的值设置为 production,启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPluginUglifyJsPlugin
  • none:不使用任何默认优化选项
module.exports={
    //...
    mode:'development',
    module:{
        //...
    }
}

现在执行 npx webpack打包,不用传入参数了

3.loader

让webpack支持非js json的模块

  • babel-loader (处理js) 使用babel-loader将es6转为es5 安装babel-loader

    npm install babel-loader --save-dev
    

    创建webpack.config.js配置:

    module.exports = {
        module:{
            rules:[
                {
                    test:/\.jsx?$/,//匹配文件类型
                    use:['babel-loader'],//使用什么loader
                    exclude:/node_modules/,//排除node_modules
                }
            ]
        }
    }
    

    然后还需要配置babel,还需要安装依赖:

    npm install @babel/core @babel/preset-env @babel/   plugin-transform-runtime --save-dev
    
    npm install @babel/runtime @babel/runtime-corejs3
    

    创建.babelrc文件,配置:

    {
        "presets": ["@babel/preset-env"],
        "plugins": [
            [
                "@babel/plugin-transform-runtime",
                {
                    "corejs": 3
                }
            ]
        ]
    }
    

    babel的配置可以写在.babelrc中,也可以在 webpack.config.js 中进行配置。

    在webpack中配置 babel,

    module.exports = {
        module: {
            rules: [
                {
                    test: /\.jsx?$/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ["@babel/preset-env"],
                            plugins: [
                                [
                                    "@babel/plugin-transform-runtime",
                                    {
                                        "corejs": 3
                                    }
                                ]
                            ]
                        }
                    },
                    exclude: /node_modules/
                }
            ]
        }
    }
    
  • css-loader (处理css) 要在js中importcss文件,要使用style-loader和css-loader

    • style-loader 将css插入到html
    • css-loader 将css文件打包到js中 安装style-loader和css-loader
    npm install style-loader css-loader --save-dev
    

    webpack.config.js配置:

    module.exports = {
        module:{
            rules:[
                {
                    test:/\.jsx?$/,//匹配文件类型
                    use:['babel-loader'],//使用什么loader
                    exclude:/node_modules/,//排除node_modules
                }
            ]
        }
    }
    

    创建/src/index.css文件,随便写点样式:

    body{
        background-color:pink;
    }
    

    src/index.jsimport index.css

    import './idnex.css'
    

    执行打包 创建index.htmlmainjs 引入

    <script src="./dist/main.js"></script>
    

    在浏览器查看html,样式生效 除了上述loader还有很多常用loader

    • 样式文件处理有less-loaderpostcss-loadersass-loader等等
    • 图片/字体文件处理有url-loaderfile-loader

4.plugin

webpack的功能扩展,对输出的资源进行二次加工 上面我们手动创建index.html文件在浏览器中查看,有时我们会在打包文件中带上 hash,内容改变后生成的js文件名会不同,

  • 所以要动态创建html文件,可以使用html-webpack-plugin

    1. 新建public目录,在里面创建index.html
    2. npm install html-webpack-plugin -D安装插件
    3. webpack.config.js中添加配置
      const HtmlWebpackPlugin = require('html-webpack-plugin');
      module.exports = {
          mode:'development',
          module:{
              //...
          },
          plugins:[
              new HtmlWebpackPlugin({
                  template:'./public/index.html',
                  filename:'index.html',//打包后的文件名
              })
          ]
      }
    

    执行打包,此时dist目录下生成了index.htmlmain.js而且html文件中自动引入了js文件

  • 每次构建前先删除上一次的构建,可以使用clean-webpack-plugin

    1. npm install clean-webpack-plugin -D安装插件
    2. webpack.config.js中添加配置
      const { CleanWebpackPlugin } = require('clean-webpack-plugin');
      module.exports = {
          entry:'./src/index.js',
          output:{
              filename:'main.js',
              path:path.resolve(__dirname,'dist')//必须绝对路径
          }
          mode:'development',
          module:{
              //...
          },
          plugins:[
              new CleanWebpackPlugin()
          ]
      }
    

    还有很多常用的插件,参考官方文档配置

简单实现loader和plugin

  1. 简单实现less-loadercss-loaderstyle-loader 1. 创建my-loaders目录,创建文件my-less-loader.jsmy-css-loader.jsmy-style-loader.js; 2. my-less-loader.js中使用less的api将less语法转换成css语法,安装less npm install less -D
    const less = require('less');
    module.exports = function(source){
        less.render(source,(error,output)=>{
            this.callback(error,output);
        })
    }
    
3. `my-css-loader.js`将css序列化
    ```js
    // 序列化css
    module.exports = function(source){
        return JSON.stringify(source);
    }
    ```
4. `my-style-loader.js`创建`style`标签,将内容插入`style`标签,将`style`标签插入`header`
    ```js
    module.exports = function(source){
        return `
            cosnt tag = document.createElement("style");
            tag.innerHtml = ${source};
            document.header.appendChild(tag);
        `
    }
    ```
修改webpack.config.js
```js
module.exports={
    module:{
        rules:[
            {
                test:/\.less$/,
                use:['my-style-loader','my-css-loader','my-less-loader']
            }
        ]
    }
    resolveLoader:{
        modules: ['node_modules','./my-loaders'],//配置webpack从哪里去找依赖, 默认值node_modules
    },
}
```

2. 简单实现一个plugin plugin是一个class,有一个核心方法apply,在插件安装时会被调用,接收compiler对象作为参数,可以在apply中访问到compiler对象 接下来实现一个统计输出到dist目录文件的清单 1. 创建my-plugin,新建TxtWebpackPlugin.js文件 2. compiler对象提供了很多钩子,在emit钩子中处理 js class TxtWebpackPlugin { apply(compiler){ compiler.hooks.emit.tap('TxtWebpackPlugin',complation=>{ let res = ''; for(let key in compilation.assets){ res += key + '\n'; } res += 'fileList.txt'; compilation.assets['fileList.txt'] = { source: function () { return res; }, size: function () { return 1; } }; }) } } module.exports=TxtWebpackPlugin; 执行打包后dist目录下会输出fileLit.txt文件,内容: main.js index.html fileList.txt 这样就完成了一个非常简单的plugin