美文网首页
webpack4笔记

webpack4笔记

作者: 瓢鳍小虾虎 | 来源:发表于2021-10-29 11:13 被阅读0次

    安装

    // 先初始化项目,创建package用于记录依赖
    npm init
    
    // 安装webpack和webpack-cli,-D表示 -dev,开发环境用的包,使用webpack4需要额外安装webpack-cli
    npm i webpack@4 webpack-cli -D
    
    

    五大核心概念

    entry:打包入口,支持多入口打包
    output:输出,可以配置输入路径,文件名等
    loader:webpack只理解javascript语法,loader可以把其他类型的文件如css、less、sass、image、vue等转成js代码。
    plugin:负责处理打包优化级相关的事,如设置环境变量、代码压缩等
    mode:webpack4特有概念,指开发模式,默认production生产模式,可以设置为development开发模式,不同模式会自动开启一些内置好的plugin。

    const { resolve } = require('path')
    
    module.exports = {
      mode: 'development', // 默认production,开发环境请使用development
      entry: './src/index.js',
      output: {
        filename: 'bundle.js',
        // 这个参数要求绝对路径,因此需要使用node的path模块帮助生成
        // __dirname是内置变量指向当前js文件的目录绝对路径
        path: resolve(__dirname, 'dist'),
    
      },
      // loader配置
      module: {
        rules: []
      },
      // plugin配置
      plugins: []
    }
    

    指定配置文件

    默认配置文件名 webpack.config.js
    也可以执行命令的时候指定自定义配置文件:webpack --config webpack.config.dev.js
    可以在package.js中配置scripts脚本:

    "scripts": {
      "webpack --config webpack.config.dev.js"
    }
    

    js相关

    js压缩:

    webpack4已经内置了UglifyJsPlugin,只要mode设置成production就可以做压缩。

    js兼容性处理:

    npm install -D babel-loader @babel/core @babel/preset-env

    webpack 4.x || 5.x | babel-loader 8.x | babel 7.x

    @babel/core:核心解析库
    babel-loader:webpack需要用的loader
    @babel/preset-env:loader的预设配置,默认支持基本的语法转换如const,promise这种不支持,需要额外添加配置指定兼容版本

          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage', // 按需加载兼容性选项
                    corejs: {
                      version: 3,
                    },
                    // 指定兼容最低浏览器版本
                    targets: {
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17',
                    },
                  },
                ],
              ],
            },
          },
    

    动态加载的语法支持:
    使用import()来实现动态加载的时候会报如下错误



    貌似babel7还不太完善,这里额外下了个core-js包,问题被解决
    npm i -D core-js


    css相关

    css:
    npm i -D style-loader@2 css-loader@5

    webpack4不要用最新版本,使用file-loader打包图标库报错


    // loader配置
      module: {
        rules: [
          { // 处理css
            test: /\.css$/,
            // use中配置的loader是倒叙执行的
            use: [
              'style-loader', // 创建style标签,将js中的css模块插入到页面上
              'css-loader', // 将css文件转换成js模块
            ]
          }
        ]
      },
    

    less:
    npm i less-loader@7 less -D

    注意:less-loader8.0以后就不支持webpack4了


    {
            test: /\.less$/,
            use: [
              'style-loader',
              'css-loader',
              'less-loader'
            ]
          }
    

    css兼容性处理:

    npm i -D postcss-loader@4 postcss@8 postcss-preset-env@7

    注意postcss-loader从版本5.0以后只支持webpack5

    postcss是核心解析api
    postcss-loader是webpack需要用的loader
    postcss-preset-env是postcss-loader支持的插件,可以配置最低要求浏览器兼容版本,这里是通过package.json上配置browserlist指定具体版本
    postcss-loader必须写在css-loader之前,其他样式loader如less-loader后面:

          {
            test: /\.less$/,
            use: [
              // 'style-loader',
              MiniCssExtractPlugin.loader, // 替代style-loader,提取css文件为单独文件
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  postcssOptions: {
                    plugins: [
                      'postcss-preset-env'
                    ]
                  }
                }
              },
              'less-loader'
            ]
          },
    

    package.json追加配置:

      "browserslist": {
        "development": [
          "last 1 chrome version",
          "last 1 firefox version",
          "last 1 safari version"
        ],
        "production": [
          ">0.2%",
          "not dead",
          "not op_mini all"
        ]
      }
    

    同时需要在webpack.config.js指定当前nodejs环境变量,postcss-preset-env会去取当前执行环境,默认production。

    process.env.NODE_ENV = "development"
    

    css提取:

    npm i -D mini-css-extract-plugin@1
    npm官网

    安装的时候注意版本,2.0以后就不支持webpack4了。


    css-loader会把引入的css文件转为js和js编码打包在一起,如果希望打包后css单独提取到外部文件并用link标签引入,需要安装插件mini-css-extract-plugin,同时用这个插件自带的loader替代style-loader。

    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    
    //...
    
    module: {
      rules: [
        {
            test: /\.less$/,
            use: [
              // 'style-loader',
              MiniCssExtractPlugin.loader, // 替代style-loader,提取css文件为单独文件
              'css-loader',
              'less-loader'
            ]
          },
          { // 处理css
            test: /\.css$/,
            // use中配置的loader是倒叙执行的
            use: [
              // 'style-loader', // 创建style标签,将js中的css模块插入到页面上
              MiniCssExtractPlugin.loader, // 替代style-loader,提取css文件为单独文件
              'css-loader', // 将css文件转换成js模块
            ]
          }
      ]
    },
    plugins: [
      new MiniCssExtractPlugin({
        filename: 'css/[hash:8].css'
      })
    ]
    
    

    这里有时候会遇到这样的问题:
    css提取到指定目录后,样式中图片路径会加载不到的问题:
    比如url-loader处理后图片加载地址为assets/img/xxx.png,如果MiniCssExtractPlugin.loader配置了publicPath为css,最终图片地址就会变成css/assets/img/xxx.png导致找不到图片,因为assets并不在css目录下,而是在根目录下。通过查看官网例子,得到如下配置方式:

    // loader...
    module: {
       rules: [
         {
           loader: MiniCssExtractPlugin.loader,
           options: {
            publicPath: '../',
           },
         },
       ]
    }
    
    
    // plugin...
    plugins: [
     new MiniCssExtractPlugin({
          filename: 'css/[name].[contenthash:8].css',
        }),
    ]
    

    这样可以做到css文件提取到指定目录,同时样式中图片地址不会拼接错误

    css压缩:

    npm i -D optimize-css-assets-webpack-plugin@6

    optimize-css-assets-webpack-plugin@4.0.0 version and above supports webpack v4.
    webpack4使用optimize-css-assets-webpack-plugin4.0.0及以上的版本
    顺带记一下webpack5要使用css-minimizer-webpack-plugin

    本例使用的是optimize-css-assets-webpack-plugin@6,需要postcss8.0及以上支持

    const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
    
    //...
    
    plugins: [
        new OptimizeCssAssetsWebpackPlugin()
      ]
    

    image

    npm i -D url-loader@4 file-loader@6 html-loader@0

    webpack4使用老版本html-loader 0.5.5,
    新版本需要查看官网html-loader

    url-loader依赖file-loader,所以2个都需要安装
    url-loader可以处理css中的image
    html-loader负责处理html中的image标签,把image标签中的图片转成js模块供url-loader处理,使用html-loader要注意配置url-loader的esModule:false

          {
            test: /\.(jpg|jpeg|png|gif)$/,
            // url-loader依赖file-loader,所以需要安装url-loader和file-loader
            use: 'url-loader',
            options: {
              // 小于8kb就会base64处理,优点是减少请求数,减轻服务端压力,
              // 缺点是文件体积会变大,通常12kb以内可以考虑配置
              limit: 8 * 1024,
              // url-loader默认使用es6模块解析js,但是html-loader解析出来的是commonjs模块,
              // 需要如下配置才能正常加载image标签图片资源
              esModule: false,
              outputPath: "img" // 打包到img目录下
            }
          },
          {
            test: /\.html$/,
            // html-loader负责处理image标签中的图片路径,负责引入图片让url-loader加载
            use: 'html-loader'
          }
    

    html相关

    html 模板copy:
    npm i -D html-webpack-plugin@4
    作用:创建html文件,自动引入js/css

    版本问题:



    报错原因是版本不兼容,最新的html插件已经升级到5,而使用的webpack版本是4
    需要指定版本安装html插件:npm i -D html-webpack-plugin@4

    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    //...
    
    // plugin配置
      plugins: [
        new HtmlWebpackPlugin({
          // 默认只会创建空html,template用于复制自定义html,在基础上插入css和js
          // 可以创建“app”标签,引入cdn库等
          template: './src/index.html'
        })
      ]
    
    

    html压缩:

    需要在HtmlWebpackPlugin中加2个配置项,用于移除空格/空行、移除注释

      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
          minify: {
            collapseWhitespace: true, // 移除空格
            removeComments: true, // 移除注释
          }
        })
      ]
    

    其他资源打包

    字体图标:字体图标是在css中被引入的,需要使用url-loader才能正确解析出地址,可以使用url-loader提取。

      { // 处理字体图标,只会在样式文件中引入,所以使用url-loader提取
        test: /\.(eot|svg|ttf|woff|woff2)/,
        loader: 'url-loader',
        options: {
          name: '[name].[contenthash:8].[ext]',
          limit: 8 * 1024, // 这个选项需要配置,默认不限制文件大小
          outputPath: 'assets/font',
        },
      },
    

    可以直接入口js引入iconfont.css

    import './font/iconfont.css'
    

    根据iconfont.css内容copy对应的字体库文件,整个字体图标目录都copy过来也可以,demo_index.html还可以查看图标样式。

    image.png

    其他文件都可以使用file-loader统一打包到配置的目录下。

    { // 其他文件,没有在样式引入的可以使用file-loader提取到指定目录下
        exclude: /\.(html|css|js|less|jpg|jpeg|png|gif|eot|svg|ttf|woff|woff2)/,
        loader: 'file-loader',
        options: {
          name: '[name].[contenthash:8].[ext]',
          outputPath: 'assets',
        },
      },
    

    devServer

    npm i -D webpack-dev-server@4
    注意使用的版本,这里安装的是4.0以后的版本。需要:node >= v12.13.0、webpack >= v4.37.0,webpack-cli >= v4.7.0
    webpack-dev-server文档

    v3和v4的差异请参考官方文档webpack-dev-server迁移

    devServer打包好的内容会存在内存中,并不会在打包目录中。

    //...
    
     devServer: {
        // 项目构建后目录
        static: {
          directory: resolve(__dirname, 'public'),
        },
        // gzip压缩
        compress: true,
        port: 3000,
        // 自动打开浏览器
        open: true,
      },
    

    优化项

    模块热替换:

    模块热替换(HMR):只改了一处js或者css文件,只重新打包加载这一部分,不要更新整个项目所有模块。
    需要处理的文件:

    1. html:默认不支持,需要刷新整个页面,单页面通常不会修改入口页面,如果使用vue-loader解析组件,会自带hmr功能
    2. css:style-loader已经支持,所以开发环境使用style-loader,生产环境才提取css
    process.env.NODE_ENV = 'development';
    const isProductionMode = process.env.NODE_ENV === 'production';
    
    //...
    
    [
    isProductionMode ? MiniCssExtractPlugin.loader : 'style-loader',
      'css-loader', 
    ]
    
    1. js:devserver默认会开启hot选项,但是会刷新所有模块,入口js无法控制,必然会导致全模块刷新,其他js可以通过在入口加一段代码控制,达到hmr功能。
    if (module.hot) {
      module.hot.accept(['./a.js', './b.js'], (name) => {
        console.log(`${name} 被更新`);
      });
    }
    

    这意味着我们需要维护所有js文件的列表...
    好在大多数情况下,我们使用的组件loader自带了hmr功能,如vue-loader、react Hot Loader,因此这个配置基本可以省略。

    source-map:

    source-map是一种源代码映射技术,可以帮助开发人员快速定位代码错误。

    [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

    //...
    devServer:{},
    devtool: 'source-map' // 增加源码映射构建
    

    打包方式和调试体验:

    1. inline-和eval-前缀的source-map会把sourcemap代码构建到bundle.js中。
      inline-在bundle中有单独的一块区域存放sourcemap代码;而eval-会在每个依赖文件的eval函数中追加sourcemap代码。排错的体验基本一样。
    2. 除了inline-和eval-前缀的source-map,其他的选项都会在外部生成source-map代码。
    3. hidden-不会让我们看到源代码,只能看构建后bundle的代码。比较适合生产环境定位代码,需要开发人员对源代码熟悉。
    4. nosources-也不会让我们看到源代码。
    5. cheap-和cheap-module-定位的粒度为行,不会具体到哪一句代码。
    6. 什么前缀都不加也是在外部构建映射代码,调试体验自然是最好的。

    调试体验:
    source-map > cheap- ...

    打包速度:
    eval > inline > cheap ...
    eval-cheap-source-map是最快的

    常规配置:

    开发环境通常使用eval-source-map,react和vue脚手架的默认配置也是这个
    如果希望速度更快,可以考虑eval-cheap-module-source-map

    生产环境需要考虑2个问题:

    1. 不能使用内联,会使bundle体积变大,因此不能考虑eval-和inline-
    2. 是否要线上调试代码,如果需要,可以考虑source-map,或者cheap-module-source-map能打包快一些。如果不需要调试,个人觉得就不要配置devtool了,不然会多打个map文件。
      更详细说明可以查看webpack-devtool官方文档

    oneOf:

    优化loader处理效率:对于那些只会被一种loader处理的文件,可以放到oneOf选项内,避免每次都要被所有loader检查一遍。

    const oneOfLoaders = [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {}
      },
      {
        {
        test: /\.less$/,
        use: [
          ...commonCssLoaders,
          'less-loader',
        ],
      },
      { // 处理css
        test: /\.css$/,
        use: [
          ...commonCssLoaders,
        ],
      },
      }
    ]
    
    //...
    
    module: {
        rules: [
          {
            test: /\.xxx$/,
            enforce: true, // 如果oneOf内部包含了对此类型文件处理,需要加上此项保证先被命中
            loader: 'xxx-loader'
          },
          {
            oneOf: [...oneOfLoaders],
          },
        ],
      },
    

    缓存:

    缓存一般用于生产环境,主要包括2方面:

    1. babel-loader打包缓存配置:babel-loader会在本地默认一个目录下缓存打包的结果,下次打包的时候会优先读取缓存。更多详细配置可以查看webpack babel-loader文档
    {
      test: /\.js$/,
       exclude: /node_modules/,
       loader: 'babel-loader',
       options: {
        cacheDirectory: true, // 开启构建缓存
        presets: [
          '@babel/preset-env'
        ]
       }
    }
    
    1. 静态资源缓存:这里主要指通过强制缓存控制js、css、img、字体图标等静态资源缓存,让用户访问页面变得快速。注意html文件不要缓存,静态资源打包输出的文件名要带上contenthash值,这样需要更新文件的时候浏览器就会去下载新的文件而不是用缓存。
      可以参考:关于浏览器缓存nginx配置代理缓存

    关于hash的配置:
    webpack中,hash有3种:hash、chunkhash、contenthash。
    hash:每次构建都会生成一个hash,所有文件共享。这显然不是我们想要的。
    chunkhash:属于同一个chunk的文件共享一个chunkhash。就比如一个入口下与入口文件有依赖关系的子文件都属于一个chunk,例如index.js中引入了css文件,那么css文件和index属于一个chunk,即使css后来用插件被提取出去了。
    contenthash:这个hash是根据最终输出的文件内容生成的。contenthash可以用于缓存和更新。

    tree shaking:

    通常我们引入一个js文件,不见得所有的函数和方法都会被引用,有的可能是废弃的代码,tree shaking的作用就是不打包未被引用的方法或对象。

    tree shaking的使用很简单:

    1. 使用import 导入,即es6的模块化语法
    2. mode设置为production
      webpack会自动进行tree shaking。

    代码分割(code split):

    如果我们的项目由单页面发展为多页面,就意味着需要多个入口js(html可以共用一个,作为基础模板),比如用户入口,商家入口,管理员入口等。
    这时候会遇到重复打包的问题,例如jquery,会被打包进了2个chunk中。

    webpack4以后提供了SplitChunksPlugin帮我们完成了这一需求,主要从以下几个角度考虑分割chunk

    1. 首先node_modules目录中的代码会被直接提取出去,这项功能单页面也适用。
    2. 引入的模块体积大于限定(默认20k)会被分割成单独chunk
    3. 按需加载,并发请求过多会被提炼成单独chunk
    4. 页面初始化,并发请求过多会被提炼单独chunk

    常规操作:

    // 这样一定会把引用的node_modules中的库抽离到单独的chunk中,
    // 其他根据判断规则自动决定是否再抽离chunk
    optimization: {
        splitChunks: {
          chunks: 'all',
        },
      },
    

    如果你想指定自己的模块被提炼出单独chunk,无视任何条件,可以使用如下的方式:

    import(/* webpackChunkName: 'c' */'./c').then(c => {
      console.log(c.paipai('fang'));
    })
    

    懒加载和预加载:

    默认代码分割后,js是并行加载的,页面在创建dom的时候,会被不必要的js模块加载造成延迟创建,这会导致体验问题。
    懒加载就是开始不加载js代码,用指定的交互行为控制用时才加载。如果加载文件体积太大会可能会出现体验问题。
    预加载会等到浏览器空闲的时候再加载,原理是link标签的preload属性控制。空闲具体是指预加载不会打扰dom加载和window.onload事件。
    配置过后可以查看页面有没有类似的标签
    <link as=script href=/js/app.69189fdd.js rel=preload>
    <link as=style href=/css/app.f60416c7.css rel=preload>
    原理和兼容性介绍

    // 懒加载
    btn.onclick = ()=> {
      import(/* webpackChunkName: 'c' */'./c').then(c => {
        console.log(c.paipai('fang'));
      })
    }
    
    // 预加载
    import(/* webpackChunkName: 'c', webpackPrefetch: true */'./c').then(c => {
      console.log(c.paipai('fang'));
    })
    

    https://webpack.docschina.org/guides/lazy-loading/
    查看文档发现vue的懒加载只需要import()的方式。可以参看dynamic-imports-in-vue-js-for-better-performance

    使用cdn:

    有些第三方库,如vue,jquery等,可以抽离出去,使用外网的免费cdn连接加载,这样可以减少打包体积。当然有时候内网部署的话,把这些不会变化的库提炼出来改为link插入也是类似效果,只不过cdn的网络理论上会好一些,但是稳定性不确定,毕竟是外网链接。
    建议生产环境使用cdn,开发环境使用打包方式引入。
    cdn网站比如:https://www.bootcdn.cn/
    其他的可以自己查找

    <!-- 在body结尾加上 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.common.prod.min.js"></script>
    
    // webpack.config.js中
    {
      externals: {
        vue: 'Vue'
      }
    }
    

    使用dll技术:

    dll技术可以告知webpack,打包的时候忽略哪些库。这样打包的时候就不会打包这些库。除此之外,需要事先把这些库抽离出来,配置好映射关系(manifest),再通过插件在打包的时候把这些库通过script引入到html中去。

    相比external,dll也是一种很不错的第三方库抽离方案,即可以减少打包体积,提高开发效率,也不受外网环境影响。

    具体步骤:

    1. 单独打包指定库:
      先创建一个单独的webpack配置文件,这里命名为webpack.dll.config.js:
    const { resolve } = require('path');
    /* eslint-disable */
    const webpack = require('webpack');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    /* eslint-enable */
    
    module.exports = {
      mode: 'production',
      entry: {
        dll: ['jquery', 'moment'],
      },
      output: {
        filename: '[name].js',
        path: resolve(__dirname, 'dll'),
        library: '[name]_[hash:10]', // 打包库对外暴露的引用命名
      },
      plugins: [
        new CleanWebpackPlugin(),
        // 用于产生manifest文件,用于映射打包文件
        new webpack.DllPlugin({
          name: '[name]_[hash:10]',
          path: resolve(__dirname, 'dll/manifest.json'),
        }),
      ],
    };
    

    这里用到了webpack.DllPlugin,主要用来生成manifest.json映射文件
    需要抽离的库在entry处配置
    执行命令webpack --config webpack.dll.config.js
    会在指定dll目录下生成2个文件dll.js和manifest.json

    这里发现个问题就是manifest.json只能映射一个文件,所以只能抽离一个包,
    entry配置多个入口虽然可以打出多个包,但是manifest只会引最后一个,
    这会产生一个体积过大的问题,个人感觉这个方案还是比较适合开发环境

    1. webpack.config.js文件中配置manifest映射关系,这样webpack打包就会根据映射文件不把指定文件打包到bundle中,同时根据映射文件修改库引用名(就是这个[name]_[hash:10])
    const webpack = require('webpack');
    
    //...
    
    plugins: [
    new webpack.DllReferencePlugin({
      manifest: resolve(__dirname, 'dll/manifest.json'),
    }),
    ]
    

    此时再打包会发现,bundle体积减小很多,重复打包的速度会快很多。但是因为第三方库没有打包进来,就没法引用到,所以还需要把dll.js通过script标签引用到html中。

    1. 使用插件引入dll.js
      需要先下载npm包:
      npm i -D add-asset-html-webpack-plugin

    这个包依赖html-webpack-plugin,具体版本要求可以查看官网add-asset-html-webpack-plugin

    然后就是配置plugin:

    const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
    
    //...
    
    plugins: [
        // 将dll.js单独打包到指定目录中,并压缩,同时html中引入script标签
        new AddAssetHtmlPlugin({
          filepath: resolve(__dirname, 'dll/dll.js'),
          outputPath: 'js',
        }),
    ]
    

    辅助小插件

    clean-webpack-plugin:
    注意关注npm官方文档,目前支持webpack4+,node10+
    npm i -D clean-webpack-plugin

    const {CleanWebpackPlugin} = require('clean-webpack-plugin')
    
    //...
    
    plugins: [
        new CleanWebpackPlugin()
    ]
    

    代码规范

    npm i -D eslint eslint-webpack-plugin eslint-config-airbnb-base eslint-plugin-import

    eslint:核心解析库
    eslint-webpack-plugin:取代了eslint-loader,作为webpack的plugin,内置了一些常用配置
    eslint-config-airbnb-base:es规范配置库,支持es6+的语法,如果是react体系需要用eslint-config-airbnb替代
    eslint-plugin-import:帮助webpack导入代码规范库

    eslint-webpack-plugin有些常用配置如屏蔽node_modules这个插件默认配置了,基本零配置直接用就可以,如果使用vscode,建议配置好IDE插件自动格式化,如果还有报红报黄也一目了然,解决好了才允许提交,这样开发人员基本不用操心代码规范问题。

    有时候开发测试代码如console想暂时保留,可以先屏蔽eslint检查。
    代码中屏蔽eslint检查以下几种方式:

    1. 文件顶部 /* eslint-disable / 整个文件不检查,
      也可以指定规则整个文件不检查/
      eslint-disable no-console */,多个规则空格隔开
    2. // eslint-disable-next-line 单行不检查
    3. 指定范围不检查:/* eslint-disable / 和 / eslint-enable */ 之间的代码都不会检查。
    /* eslint-disable */
    
    console.log('aaa')
    
    /* eslint-enable */
    
    1. 还可以指定特定规则不检查
    /* eslint-disable no-console */
    
    alert('lalala')
    console.log('aaa')
    
    /* eslint-enable no-console */
    
    1. 还可以在配置中指定不处理某条规则:
    // package.json中
    "eslintConfig": {
        "extends": "airbnb-base",
        "rules": {
          "no-console":"off"
        }
      }
    

    webpack.config.js:

    const EslintWebpackPlugin = require('eslint-webpack-plugin');
    
    //...
    
    plugins: [
        new EslintWebpackPlugin()
    ]
    

    package.json追加配置:

    //...
    
    "eslintConfig": {
        "eslintConfig": {
          "extends": "airbnb-base",
          "rules": {
            "no-console":"off"
          },
          "parserOptions": {
            "ecmaVersion": 2020
          }
        }
      }
    

    在使用webpack做代码分割的时候,如果用到动态import,默认eslint检查是不通过的,"ecmaVersion": 2020可以解决这个问题~

    如果你是vue使用者,还需要安装eslint-plugin-vue,可以对vue文件组件进行的规范检查。

    npm i -D eslint-plugin-vue

    配合vscode的eslint插件,可以让ide正确的识别vue组件内容和自动格式化。同时eslint配置也可以写到单独的eslintrc.js文件中。

    module.exports = {
      extends: [
        'plugin:vue/essential',
        'airbnb-base',
    
      ],
      rules: {
        'no-console': 'off',
        'no-new': 'off',
        'import/no-unresolved': 'off',
        'import/extensions': 'off',
        'space-before-function-paren': 'off',
        'vue/multi-word-component-names': 'off',
      },
      parserOptions: {
        ecmaVersion: 2020,
      },
    };
    

    其他功能

    resolve配置:

    1. 别名:
      resolve: { // 配置解析模块规则,比较常用的就是别名,缺点是,ide可能无法正常提示路径
        alias: {
          $css: resolve(__dirname, 'src/css'),
          $assets: resolve(__dirname, 'src/assets'),
          $js: resolve(__dirname, 'src/js'),
        },
      },
    

    如果你用了eslint,打包的时候会检查出错误“import/no-unresolved”,需要配置一下eslint配置文件,这里是直接写在package.json中:
    屏蔽掉这条规则,打包的时候不需要eslint检查,如果你vscode安装了eslint插件,也会跟着屏蔽掉这个规则。

      "eslintConfig": {
        "rules": {
          "import/no-unresolved": "off"
        },
      }
    

    还有一种方式是,下载插件:
    npm i -D eslint-import-resolver-webpack
    然后,配置如下:

      "eslintConfig": {
        "rules": {
          "import/no-unresolved": "off"
        },
        "settings": {
          "import/resolver": {
            "webpack": {
              "config": "./webpack.config.js"
            }
          }
        }
      }
    

    多出来的这些配置主要是帮助插件找到别名配置,可以让eslint正确识别路径,打包不会报错了,
    但是ide还是会标红,最终"import/no-unresolved": "off"这条规则还是得加上去,
    既然都屏蔽了,eslint-import-resolver-webpack也没有必要用了。

    1. 文件扩展名
      resolve: {
        // 配置可省略的文件后缀名默认是js和json
        extensions: ['.js', '.json', '.less', '.css', '.vue'],
      },
    

    根据自身项目情况,可以追加文件扩展名,这样写代码的时候可以省略文件扩展,当然如果文件同名但是扩展名不同,解析器会优先找js文件,开发中最好不要有同名的情况。

    webpack官方文档

    相关文章

      网友评论

          本文标题:webpack4笔记

          本文链接:https://www.haomeiwen.com/subject/wbjsrktx.html