webpack面试题总结

149 阅读2分钟

一、webpack配置问题

  • 常用的loader有哪些?
    样式:style-loader、css-loader、less-loader、postcss-loader; 图片等:url-loader、file-loader; es6:babel-loader。
  • 常用的plugin有哪些?
    clean-webpack-plugin、html-webpack-plugin、mini-css-extract-plugin; webpack自带的插件:HotModuleReplacementPlugin、providePlugin(shimming)
  • loader和plugin有什么区别?
    loader是当我们进行打包我们的文件时,处理不同类型的文件,处理模块。plugiin是在打包的时候具体时刻,进行处理事件。
  • webpack如何抽离压缩css文件?
    利用mini-css-extract-plugin插件抽离css文件,optimize-css-assets-webpack-plugin用于压缩css文件。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
...
module:{
  rules:[
      {
          test:/\.css$/,
          use:[
            MiniCssExtractPlugin.loader,
              {   
                  loader:"css-loader",
                  options:{
                      importLoaders:1
                  }
              },
              "postcss-loader"
          ],
      },
...
plugins: [new MiniCssExtractPlugin({
    filename:'css/main.[contenthash].css'
})]
optimization: {
    minimizer: [new OptimizeCssAssetsPlugin({})]
}
  • webpack怎样抽离公共代码和第三方库?
    利用splitChunkPlugin可以实现代码分割,在缓存组配置分割第三方库和公共代码。
optimization: {
    splitChunks:{
        cacheGroups: {
            // 如果引入的包是node_modules里面的内容,会进入到这里的配置
          vendors: {
            test: /[\\/]node_modules[\\/]/,//检测引入的第三方库是不是node_modules里面的内容
            priority: -10,
            filename: 'vendors.js' 
          },
          // 如果引入的包不是node_modules里面的内容,会进入到这里的配置
          default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true,
            filename: 'common.js'
          }
        }
    }
}
  • webpack如何实现异步加载js?
    利用import引入,/* webpackChunkName:"lodash"*/设置打包输出的文件名。
function getComponent () {
  return import(/* webpackChunkName:"lodash"*/'lodash').then(({default: _}) => {
    var element = document.createElement('div')
    element.innerHTML = _.join(['a','b','c'],'***')
    return element
  })
}
// 点击页面才会执行
document.addEventListener('click', () => {
  getComponent ().then((element) => {
    document.body.appendChild(element)
  })
})

  • @babel/polyfill如何按需引入?
    默认的Babel只⽀持let等⼀些基础的特性转换, Promise等⼀些还有转换过来,这时候需要借助@babel/polyfill,以查找目标环境中缺少的功能,并且仅包括所需的polyfill。
#业务代码打包场景
//新建.babelrc文件
{"presets": [
    [
      "@babel/env",
      {
        //兼容的浏览器设置
        "targets": "> 0.2%, not dead",
        //按需注入,使用了usage,会自动引入import "@babel/polyfill",
        //无需在js中引入
        "useBuiltIns": "usage",
      }
    ]
]
}

  • module、chunk和bundle的区别?
    module指各个源码文件,webpack一切皆模块;而chunk指entry入口文件、import懒加载、splitChunk多模块合成的;bundle指最终输出的文件。
  • 如何配置多页面打包?
    打包之后有两个html页面,一个引入index.js打包之后的文件,一个引入list.js打包之后的文件。那么需要配置两个entry,遍历entry设置chunks。
    // 入口文件
    entry: {
        main: './src/index.js',
        list: './src/list.js'
    },

const path = require('path')
// 将我们写的html文件,进行打包;
const HtmlWebpakcPlugin = require('html-webpack-plugin')
const makePlugins = (configs) => {
    const plugins = [new CleanWebpackPlugin()]
    const files = fs.readdirSync(path.resolve(__dirname, './dll'))
    Object.keys(configs.entry).forEach(item => [
        plugins.push(new HtmlWebpakcPlugin({
            template: './src/index.html',
            filename: `${item}.html`,
            chunks: ['runtime', 'vendors', item]
        }))
    ]);
    return plugins;
}
const configs =  {
    // 配置打包模式
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    // 入口文件
    entry: {
        main: './src/index.js',
        list: './src/list.js'
    },
    ...
}
module.exports = configs
configs.plugins = makePlugins(configs)

二、webpack性能优化

  • 怎样优化打包构建速度?
    • 优化babel-loader,明确范围,可以通过includes以及excludes等选项,进行配置不对其他库文件进行转换。
    • tread-loader, parallel-webpack, happypack 多进程打包,webpack-parallel-uglify-plugin多进程压缩。 需要注意的是:项目较大时,开启多进程打包可以提高速度;但项目较小时,由于进程开销,可能会降低速度。
    • 开发环境:开启自动刷新和热更新。
      利用webpack.HotModuleReplacementPlugin插件
    if (module.hot) {
        module.hot.accept('./number.js', function() {
            number();
       })
    }
    
    • 开发环境:使用DllPlugin提高打包速度。前端框架体积较大,构建慢,较稳定,不常更新版本,同一个版本只需构建一次。

    • 对于产出代码可以考虑三个方面:体积更小、合理分包不重复加载、速度更快内存使用更小。 小图片可以使用url-loader转换为base64编码、懒加载、bundle加contenthash缓存、利用splitChunkPlugin提取公共代码、通过Tree Shaking进行去除没有使用的包。