webpack

前言

对于前端来说,webpack当前的使用频率是非常频繁的,下面我们来探讨一下使用webpack引入三方轮子的几种方式以及其中可能出现的坑。

方式一 在入口全局引入

在入口全局引入在当前来说是最常见的方式,例如vue项目中引入vue包

import Vue from 'vue'
 new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})
1
2
3
4
5
6

这种引入方式是直接引入node_modules/vue/package.jsonmain对应的的位置,例如

"main": "dist/vue.runtime.common.js",
1

这就是引入node_modules/vue/dist/vue.runtime.common.js 如果我们需要修改指向,例如vue包的默认指向的文件vue.runtime.common.js在webpack项目中不能生效,我们可以直接指向该路径

import Vue from 'vue/dist/vue.esm.js'
1

在webpack配置中修改别名来修改引入文件的位置,在webpack.config.js文件中

resolve:{
     alias:{
          // 修改 vue 被导入时的路径    $ 表示以 vue 结尾
          "vue$":"vue/dist/vue.esm.js"
          // 给根目录下的 src 目录配置别名。方便引入文件
          // 注意:在模板组件中的 <style>引入样式 需要加 ~ 波浪线
          // 如:import '~@css/style.css'
          "@": resolve("src")
     }
}
1
2
3
4
5
6
7
8
9
10

如果你没有做任何优化,这种方式会把引入的vue包和业务代码一起打包到entry的入口文件,这当然不是我们想要的。我们可以用webpack配置来优化让从node_modules中引入的包单独打包成一个文件。

使用webpack插件CommonsChunkPlugin优化

CommonsChunkPlugin主要是用来提取第三方库和公共模块,避免首屏加载的bundle文件或者按需加载的bundle文件体积过大,从而导致加载时间过长,着实是优化的一把利器。 在webpack4+中,此插件被移除,取而代之的是optimization。下面是简单的例子

webpack3+

//业务代码与node_modules分离
...
new webpack.optimize.CommonsChunkPlugin({    
  name: 'vendor',
  minChunks: ({ resource }) => (
      resource &&
      resource.indexOf('node_modules') >= 0 &&
      resource.match(/\.js$/)
  ),
}),
...
1
2
3
4
5
6
7
8
9
10
11

webpack4+

module.exports={
    ...
    optimization:{
        splitChunks: {
        chunks: "vendor",
        minSize: 30000,
        minChunks: 1,
        maxAsyncRequests: 5,
        maxInitialRequests: 3,
        name: true,
        cacheGroups: {
            default: {
                minChunks: 2,
                priority: -20,
                reuseExistingChunk: true,
            },
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

想了解更多webpack4+的optimization配置请看这里 优化(optimization)

方式二 在entry下与入口文件一同引入

module.exports={
    entry: {
       app: ["vue","./index.js"]
    },
    ...
}
1
2
3
4
5
6

此时,vue内部的文件和index.js文件都会被打包成app.js文件,排除优化情况,这里数组里面的所有文件都会被打包成app.js

同理可以用上面的优化方式把node_modules代码打包到vendor文件中。

这种方式使用不多,主要用于单页项目中需要全局引入的包例如babel-polyfill,那么我们可以直接在这里引入

方式三 使用webpack的chunks

在webpack配置的entry中使用别名来引入包例如

module.exports={
    entry:{
        polyfill:'@babel-polyfill',
        app:'./src/index.js'
    }
}
1
2
3
4
5
6

当我们html-webpack-plugin插件没有指定对应的chunks时,entry中的polyfill和app将会被打包成两个文件(如这里会被打包成polyfill.js和app.js)引入到html文件中,这其中引入顺序决定着js代码的依赖关系,可通过chunksSortMode进行顺序调整

当然我们还可以通过html-webpack-plugin插件中的chunks属性来决定我们当前页面引入哪一个js文件

entry: {
    polyfill: 'babel-polyfill.js',
    b: './b.js',
    a: './a.js',
    d: './d.js',
    e: './e.js'
  },
...
plugins:{
    new HtmlWebpackPlugin({
      inject: true,
      filename: 'first-file.html',
      template: 'template.html',   
      chunks: ['polyfill','a', 'c']
    }),
    ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

当这个first-file.html构建成功后,会在底部插入plyfill.js、a.js、c.js到文件中

Last Updated: 6/25/2019, 12:02:55 AM