Skip to content
On this page

参考:

谈谈你对 webpack 的看法

webpack的主要原理是,它将所有的资源都看成是一个模块,并且把页面逻辑当作一个整体,通过一个给定的入口文件,webpack 从这个文件开始,找到所有的依赖文件,将各个依赖文件模块通过loader和plugins处理后,然后打包在一起,最后输出一个浏览器可识别的JS结果文件。

Webpack 具有四个核心的概念,分别是 Entry(入口)、Output(输出)、loader 和 Plugins(插件)。

  • Entry:是 webpack 的入口起点,它指示 webpack 应该从哪个模块开始着手,来作为其构建内部依赖图的开始。
  • Output:属性告诉 webpack 在哪里输出它所创建的打包文件,也可指定打包文件的名称,默认位置为 ./dist。
  • loader:可以理解为 webpack 的编译器,它使得 webpack 可以处理一些非 JavaScript 文件。在对 loader 进行配置的时候,test 属性,标志有哪些后缀的文件应该被处理,是一个正则表达式。use 属性,指定 test 类型的文件应该使用哪个 loader 进行预处理。常用的 loader 有 css-loader、style-loader 等。
  • Plugin:插件可以用于执行范围更广的任务,包括打包、优化、压缩、搭建服务器等等,要使用一个插件,一般是先使用 npm 包管理器进行安装,然后在配置文件中引入,最后将其实例化后传递给 plugins 数组属性。
js
// webpack.config.js
import path, { dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import HtmlWebpackPlugin from 'html-webpack-plugin'

export default {
  entry: './src/index.js',
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Caching',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource'
      }
    ]
  },
  output: {
    path: path.resolve(dirname(fileURLToPath(import.meta.url)), 'dist'),
    filename: '[name]-bundle.js',
    clean: true
  },
  optimization: {
    runtimeChunk: 'single',
  },
};

使用 webpack 的确能够提供我们对于项目的管理,但是它的缺点就是调试和配置起来太麻烦了。但现在 webpack4.0 的免配置一定程度上解决了这个问题。但是我感觉就是对我来说,就是一个黑盒,很多时候出现了问题,没有办法很好的定位。

webpack与grunt、gulp 的不同?

  • Grunt、Gulp是基于任务运⾏的⼯具: 它们会⾃动执⾏指定的任务,就像流⽔线,把资源放上去然后通过不同插件进⾏加⼯,它们包含活跃的社区,丰富的插件,能⽅便的打造各种⼯作流。
  • Webpack是基于模块化打包的⼯具: ⾃动化处理模块,webpack把⼀切当成模块,当 webpack 处理应⽤程序时,它会递归地构建⼀个依赖关系图 (dependency graph),其中包含应⽤程序需要的每个模块,然后将所有这些模块打包成⼀个或多个bundle。

因此这是完全不同的两类⼯具,⽽现在主流的⽅式是⽤npm script代替Grunt、Gulp,npm script同样可以打造任务流。

webpack、rollup、parcel 优劣?

  • webpack适⽤于⼤型复杂的前端站点构建: webpack有强⼤的loader和插件⽣态,打包后的⽂件实际上就是⼀个⽴即执⾏函数,这个⽴即执⾏函数接收⼀个参数,这个参数是模块对象,键为各个模块的路径,值为模块内容。⽴即执⾏函数内部则处理模块之间的引⽤,执⾏模块等,这种情况更适合⽂件依赖复杂的应⽤开发。
  • rollup适⽤于基础库的打包,如vue、d3等,Rollup就是将各个模块打包进⼀个⽂件中,并且通过Tree-shaking来删除⽆⽤的代码,可以最⼤程度上降低代码体积,但是rollup没有webpack如此多的的如代码分割、按需加载等⾼级功能,其更聚焦于库的打包,因此更适合库的开发。
  • parcel适⽤于简单的实验性项⽬: 他可以满⾜低⻔槛的快速看到效果,但是⽣态差、报错信息不够全⾯都是他的硬伤,除了⼀些玩具项⽬或者实验项⽬不建议使⽤。

Loader 和 Plugin 的不同?

  • Loader直译为"加载器",Webpack将⼀切⽂件视为模块,但是webpack原⽣是只能解析 js⽂件,如果想将其他⽂件也打包的话,就会⽤到loader, 所以Loader的作⽤是让webpack拥有了加载和解析⾮JavaScript⽂件的能⼒
  • Plugin直译为"插件",Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。在Webpack运⾏的⽣命周期中会⼴播出许多事件,Plugin可以监听这些事件,在合适的时机通过Webpack 提供的API 改变输出结果。

bundle,chunk,module 是什么?

  • bundle:是由webpack打包出来的⽂件;
  • chunk:代码块,⼀个chunk由多个模块组合⽽成,⽤于代码的合并和分割;
  • module:是开发中的单个模块,在webpack的世界,⼀切皆模块,⼀个模块对应⼀个⽂件,webpack会从配置的entry中递归开始找出所有依赖的模块。

有哪些常⻅的 Plugin?

  • define-plugin:定义环境变量
  • html-webpack-plugin:简化 html⽂件创建
  • uglifyjs-webpack-plugin:通过 UglifyES 压缩ES6 代码
  • webpack-parallel-uglify-plugin: 多核压缩,提⾼压缩速度
  • webpack-bundle-analyzer: 可视化 webpack 输出⽂件的体积
  • mini-css-extract-plugin: CSS 提取到单独的⽂件中,⽀持按需加载

有哪些常⻅的 Loader?

  • file-loader:把⽂件输出到⼀个⽂件夹中,在代码中通过相对URL去引⽤输出的⽂件
  • url-loader:和file-loader类似,但是能在⽂件很⼩的情况下以base64的⽅式把⽂件内容注⼊到代码中去
  • source-map-loader:加载额外的 Source Map ⽂件,以⽅便断点调试
  • image-loader:加载并且压缩图⽚⽂件
  • babel-loader:把 ES6 转换成 ES5
  • css-loader:加载 CSS,⽀持模块化、压缩、⽂件导⼊等特性
  • style-loader:把 CSS 代码注⼊到 JavaScript 中,通过DOM操作去加载 CSS。
  • eslint-loader:通过 ESLint 检查 JavaScript 代码

注意:在Webpack中,loader的执行顺序是从右向左执行的。因为webpack选择了compose这样的函数式编程方式,这种方式的表达式执行是从右向左的。

如何⽤webpack 来优化前端性能?

⽤webpack 优化前端性能是指优化 webpack 的输出结果,让打包的最终结果在浏览器运⾏快速⾼效。

  • 压缩代码:删除多余的代码、注释、简化代码的写法等等⽅式。可以利⽤webpack的UglifyJsPlugin和ParallelUglifyPlugin来压缩JS⽂件,利⽤ cssnano(css-loader?minimize)来压缩css
  • 利⽤CDN加速: 在构建过程中,将引⽤的静态资源路径修改为CDN上对应的路径。可以利⽤webpack对于output参数和各loader的publicPath参数来修改资源路径
  • Tree Shaking: 将代码中永远不会⾛到的⽚段删除掉。可以通过在启动 webpack 时追加参数--optimize-minimize来实现
  • Code Splitting: 将代码按路由维度或者组件分块(chunk),这样做到按需加载,同时可以充分利⽤浏览器缓存
  • 提取公共第三⽅库: SplitChunksPlugin插件来进⾏公共模块抽取,利⽤浏览器缓存可以⻓期缓存这些⽆需频繁变动的公共代码

Babel 的原理是什么?

babel的转译过程也分为三个阶段,这三步具体是:

  • 解析Parse: 将代码解析⽣成抽象语法树(AST),即词法分析与语法分析的过程;
  • 转换Transform: 对于 AST 进⾏变换⼀系列的操作,babel 接受得到 AST 并通过 babel-traverse 对其进⾏遍历,在此过程中进⾏添加、更新及移除等操作;
  • ⽣成Generate: 将变换后的 AST 再转换为JS 代码, 使⽤到的模块是 babel-generator。

Released under the MIT License.