webpack相关面试问题

1,008 阅读5分钟

1、webpack中的modules是什么?

模块,webpack支持ESMoudle、CommonJS、AMD、Assests(image,font,video,json)
1、ESMoudle:importexport
2、CommonJS:moudle.exports,导出给其他的模块;require

2、chunk和bundle分别是什么?有什么区别?

chunk是webpack打包过程中modules的集合;
webpack的打包从一个入口模块开始,通过引用关系逐个打包模块,这些module就形成一个chunk。

bundle是我们最终输出的一个或者多个打包好的文件;

关系:大多数情况下,一个chunk会产生一个bundle,但如果加了sourcemap,一个entry,一个chunk对应两个bundle;
chunk是过程中的代码块,bundle是打包结果输出的代码块,chunk在构建完成就呈现为bundle。

3、Plugin、Loader分别是什么?

Loader:模块转换器,将非js的模块转换为js能识别的模块。
本质上,是将所有类型的文件,转换为应用程序的依赖图,可以直接引用的模块。

Plugin:扩展插件,webpack运行的各个阶段,都会广播出对应的事件,插件去监听对应的事件。

4、Compiler和Complation是什么?

Compiler对象,包含了webpack环境的所有配置信息,包含options,loader,plugin,它在webpack启动的时候实例化,全局唯一的,是webpack的实例。

Complation包含了当前的模块资源,编译生成资源。webpack在开发环境下运行的时候,每当检测到一个文件的变化,就会创建一次新的Complation。

5、简单描述下webpack的打包过程?

1、初始化参数:在webpack.config.js
2、开始编译:初始化一个compiler对象,加载所有的配置,开始执行编译;
3、确认入口:根据entry中的配置,找出所有的入口文件;
4、编译模块:从入口文件开始,调用所有的loader,再去递归找依赖;
5、完成模块编译:得到每个模块被编译后最终的内容以及他们之间的依赖关系;
6、输出资源:根据得到的依赖关系,组装成一个个包含多个module的chunk;
7、输出完成:根据配置,确定要输出的文件名以及文件路径。

6、bable的原理?

1、解析Parse:将代码解析生成抽象语法树(AST),即词法分析和语法分析过程;
2、转换transform:对于AST进行变换一系列的操作,babel接受得到ast通过babel-traverse对其进行遍历,在遍历过程中进行添加、更新及删除操作;
3、生成generate:使用模块babel-generator将变换后的ast再转换为js代码;

7、常见的loader和plugin?

loader:
    file-loader:把文件输出到一个文件夹中,在代码中通过相对url去引用输出的文件;
    url-loader:和file-loader类似,但是能在文件很小的情况下以base64方式把文件内容注入到代码中;
    source-map-loader:加载额外的sourcemap文件,以方便断点调试;
    image-loader:加载并压缩图片文件;
    babel-loader:把es6转成es5;
    css-loader:加载css,支持模块化、压缩、文件导入等特性;
    style-loader:把css代码注入到js中,通过dom操作去加载css;
    eslint-loader:通过eslint检查js代码;
    vue-loader:vue中的模块加载编译;
    
plugin:
    html-webpack-plugin:简化html文件创建,压缩html文件;
    terser-webpack-plugin:压缩js代码,可以开启多线程压缩;
    optimize-css-assets-webpack-plugin:css压缩,默认压缩引擎是cssnano;

8、如何用webpack来优化前端性能?

优化输出结果,让打包在浏览器中运行快速高效;

1、压缩代码:删除多余的代码、注释、简化代码的写法;
   css可以使用optimize-css-assets-webpack-plugin:css压缩,默认压缩引擎是cssnano;
   js压缩可以使用terser-webpack-plugin,可以配置缓存和多线程压缩
2、利用cdn加速:在构建过程中,将引用的静态资源路径修改为cdn上的路径;
3、tree shaking:将代码中不会使用的片段删除。webpack4.0默认在mode=production的情况下,开启树摇。
4、code-splitting:代码分割,使用splitchunkplugin插件,抽取公共模块,利用浏览器缓存不需要频繁变动的代码.

9、如何提高webpack的打包速度?

1、利用缓存:webpack.cache\babel-loader.cacheDirectory等都可以利用缓存提高打包速度;
2、缩小文件搜索范围:
   优化loader查找范围:test include exclude三个配置项来缩小loader的处理范围;
   优化resolve.modules配置,如果第三方模块安装在了根目录下,可以直接指明这个路径:
   module.exports={
       resolve:{
           modules:[path.resolve(__dirname,'./node_modules')]
       }
   }
3、利用多线程提升构建速度:thread-loader,将loader放在一个worker池里面运行,需要放在其他的loader之前。

10、多页面应用配置?

多页面的应用配置可以通过AutoWebPlugin插件来完成构建,但是必须要遵循它的页面目录要求:

1、页面目录:
src
    index
        index.js
        index.html
    list
        index.js
        index.html
    detail
        index.js
        index.html
//webpack.config.js
entry:{
    index:"./src/index",
    list:"./src/list",
    detail:"./src/detail"
}
new htmlWebpackPlugins({
    title: "index.html",
    template: path.join(__dirname, "./src/index/index.html"),
    filename:"index.html",
    chunks:[index]
})
//使用glob.sync第三方库来匹配路径
npm i glob -D
const glob require('glob')
//多页面打包配置通用方案
const setMPA = () => {

  const entry = {};

  const htmlWebpackPlugins = [];

  const entryFiles = glob.sync(path.join(__dirname, "./src/*/index.js"));

  entryFiles.map((item, index) => {

    const entryFile = entryFiles[index];

    const match = entryFile.match(/src\/(.*)\/index\.js$/);

    const pageName = match && match[1];

    entry[pageName] = entryFile;

    htmlWebpackPlugins.push(

      new htmlWebpackPlugin({

        title: pageName,

        template: path.join(__dirname, `src/${pageName}/index.html`),

        filename: `${pageName}.html`,

        chunks: [pageName],

        inject: true

      })

    );

  });

  return {

    entry,

    htmlWebpackPlugins

  };

};

const { entry, htmlWebpackPlugins } = setMPA();

module.exports = {

  entry,

  output: {

    path: path.resolve(__dirname, "./dist"),

    filename: "[name].js"

  }

  plugins: [

    // ...

    ...htmlWebpackPlugins//展开数组

  ]

}

先总结这些,欢迎补充更正~