webpack三招必杀技

作者: 37手游技术部 | 来源:发表于2021-01-29 15:03 被阅读0次

相信每个前端同学一定都使用过webpack,作为一个划时代的构建工具,却有很多同学对他的认识还停留在怎么改个host的认知上。由于现代的脚手架极大地提高了项目搭建的效率,但是工具的便捷性,自动化和完善的配置,也让很多同学对wepback认识不深。这里我整理了几个经典的场景的webpack应用,希望对大家有帮助

一、webpack的几个核心参数

作为铺垫,首先我们先介绍以下webpack的几个核心基本配置参数,也许懂的都懂,但是这里还是作为回顾和复习进行简单说明

1 entry

接受一个对象或数组,通过该配置,我们可以设定一个或者多个入口

2 output

接受一个对象,可以设置打包输出文件的输出路径及输出文件名。如果是多个入口的情况 可以使用[name]、[hash]等作为动态参数 设定多个输出文件的命名规则

3 plugins

一个数组,可以加载多个插件作为文件处理的。常用的插件如:

uglify-webpack-plugin:压缩 javascript

clean-webpack-plugin: 删除dist目录的文件

copy-webpack-plugin 复制文件

ExtractTextPlugin:将打包中的css单独抽离出来

HtmlWebpackPlugin:webpack打包后自动生成html页面

HappyPack: 多核打包 加快打包速度

CommonsChunkPlugin/SplitChunksPlugin : 抽取公用模块

webpack.DllPlugin+webpack.DllReferencePlugin 用与多入口项目 可以把入口的共同依赖 单独打包

4.module

通过设置module.rule数组来配置loader。loader一般通过正则表达式处理指定的文件类型,常用loader有

babel-loader @babel/core @babel/preset-env:JS转ES5的全家桶,需要配套使用

css-loader:解析import进来的.css文件

style-loader:把经过处理的css以<style>标签插入html中

html-loader :解析.html文件,能够从中分析出引入的js/css/图片等数据

5.resolve

该参数设定关于路径解析的配置。常用的属性有

extensions:['.js', '.vue', '.json'],指我们在代码中import的路径可以不写后缀名,会在次数组中自动搜索预设好的后缀名

alias:{'@': resolve('src')}:路径别名,通过该设置 在代码里面些@ 就表示src目录

6.devtool

该参数有10+个枚举值,设置的是代码的sourcesouMap的打包方式。有的会把sourcesouMap打包到代码里,有个会另外存为一个.map文件,sourcesouMap的细致程度也有区分

以上就是我认为比较重要的几个核心参数,大概能了解其中的用处,在实际使用过程中可以参照文档更细致的了解其配置

二、webpack的场景应用

好了,相信上面入门的配置项大部分同学都懂,但是在实际应用过程中,因为大部分情况脚手架都帮我们做好了完善的配置,基本不需要做什么变动。但是在一些项目开发中,无法用脚手架搭建的情况就需要我们自己动手写配置。下面这里总结了几个经典的场景,看看webpack如何发挥作用

场景1:打包公用代码到第三方库

现在有两个入口JS,就叫A.js和B.js吧,内容都很简单,他们都需要引入一个第三方库 ,比如就是Jquery。那么A和B文件 的代码非常简单:

import $ from jquery

console.log($)

如果不做什么特别的设置,我们在入口entry设好A和B两个入口,然后在output设置好输出文件的名称路径等,那么我们得到了两个输出文件,两个文件插入到html中都是正常运行的,可以正确输出了引入的对象。但是这并不符合我们的优化需求。因为你会发现,尽管A B两个文件只有2句代码,但是打包输出之后 两个文件都是300多K,明显每个文件都吧jquery打包进去了。正确的做法应该是希望jquery作为一个第三方库插入到html中,A、B文件都只需要直接使用就可以了。那么下面就用webpack帮我们实现这个功能。本案例中webpack版本是4.3,webpack4对于抽离第三库的功能已经集成了该功能,我们只需要用到optimization.splitChunks属性即可,不需要额外安装插件。

optimization: {
    splitChunks: {  //分割代码块
      cacheGroups: {  //缓存组 缓存公共代码
        commons: {  //公共模块 
          name: "commons",
          chunks: "initial",  //入口处开始提取代码
          minSize: 0,      //代码最小多大,进行抽离
          minChunks: 2,    //代码复 2 次以上的抽离
        }
     }
    }
  }

通过以上这个设置,最终输出的文件讲会把公用库抽离作为我们设置的commons.js

1.png

场景2:指定不予打包的库

现在我写了一个好用的图片播放插件,具体的实现大家脑补即可,但是我的代码中也使用了jquery,代码中大量的地方使用了$()进行DOM的操作。这个插件我最终是需要作为一个npm包上传到npm社区上让大家使用的。同样不经过任何优化的话,那么我最终打包出来供大家使用的JS,都将会包含了jquery的代码,那么每个使用了我的插件的代码里 就这样多出了几百K的体积,这也不是我所希望的。这种情况下,我可以在使用说明里先给大家做一个声明,也就是这个插件将基于jquery编写,在引用该插件的时候 需要保证环境中有jquery,这样我就不需要把jquery打包到我的文件中,我的插件包可能只需要几kb即可。这个需求核心则是使用到了externals的配置,该配置可以声明指定库不会打包到代码中,而在使用的地方仅留下一个引用,这样只要插件运行环境中有这个库,那么就可以正常运行,并且插件本身不会打包这个库的代码

externals:{
  jquery:'commonjs2 jquery'
}

这里需要再额外解释一下 上面这个设置中 有一个commonjs2的字符串配置。这个地方是用来声明该库以哪个规范的形式载入到我们的代码中。所谓的规范就是只是原生js的形式或者AMD、CMD还是commonJS的规范引用进来。这里不做过多的展开,实际最常用的 其实就两个 :原生及commonJS。原生就是我们在html中 通过cdn方式引入 可以在页面直接运行的。而commonJS规范则是我们node使用的,我们基本都用这个方式 通过import或者require语法引入第三方包。而上面的案例中 我们通过import $ from jquery 也就是使用了commonJS规范,所以在设置externals时候需要声明'commonjs2 jquery'

三、webpack应用的进阶案例

这次我们打算做一个完整一点的npm包了。为了大家便于理解,那么现在我们需要做一个山寨简化版Element组件库。说到这个UI库,相信每个同学都用过了把。Element里有几十个组件供我们使用。我们可以通过以下全局代码引入:

Import ElementUI form ‘Element’

Vue.use( ElementUI )

这样在整个项目需要用到的地方 直接使用组件标签插入到模板中即可。但是如果我们只需要用到其中一个或者几个组件,我们是可以通过局部引入的方式 仅使用部分组件:

 Import { button,select }form ‘Element’

这样我们自己的代码 将只会包含以上2个引入的组件代码,其他几十个组件是不会打包到我们的代码中。下面我们就来实现这样一个需求:

  1. 项目结构

首先这是一个vue组件库,我们可以通过vuecil脚手架创建出项目,并且构建如下目录

dist  ... 
src  index.js
packages
    button / button.vue
    select / select.vue
    checkbox /checkbox.vue

这里的项目结构大家有一个直观认知即可

2.代码引用

​ 这个项目的入口为src/index.js,该文件需要实现的是install方法,因为全局引入的时候 通过Vue.use(我们的组件库),就会调用install方法 这里我们需要将其实现,实现的功能就是通过遍历对象或者数组 吧packages里面的三个vue组件注册到Vue中

Import button from ‘packages/button’
Import select from ‘packages/select’
Import checkbox from ‘packages/ checkbox’

Const components = [button ,select,checkbox]
const install = function(Vue, opts = {}) {
  components.forEach(component => {
    Vue.component(component.name, component);
  })
};
export default {
button ,
select,
checkbox, 
install 
}

而我们的三个组件则是正常的一个vue组件,这里应该不需要再给大家写伪代码了。

3.webpack配置

完成上述的基本结构下面就可以进行webpack打包配置了。首先entry肯定是我们的src/index.js 相信这里都不会有什么异议。然后重点是配置output:

output: {
    path: path.resolve(process.cwd(), './lib'),  //打包输出的路径
    filename: 'comp.common.js',,   //打包输出文件名
    library: 'COMP',  // 此项需要搭配libraryTarget使用,'commonjs2'时该项不生效
    libraryTarget: 'commonjs2' // 声明输出文件支持的规范
  },

因为我们的组件库的使用是通过import语句引入,那么libraryTarget需要设置为'commonjs2' ,跟案例二中的说法一样。libraryTarget有多个值,只有使用部分选项,才需要设置library,其他情况下 library可以不用写,写了也不会生效。如果现在输出的话,那么三个组件的代码都会被打包到comp.common.js中,那样就没有办法做局部引入了。所以这里又得用到externals这个外部扩展的配置了。

Externals{
‘./packages/button.vue’:’commonjs2 button’,
‘./packages/select.vue’:’commonjs2 select’,
‘./packages/checkbox.vue’:’commonjs2 checkbox’
} 

这里可以打包一下,生成出来的comp.common.js 可以发现只留下了引用,而三个组件本身的代码 不会被打包进来。但是这样就大功告成了吗?并没有,因为外部扩展的这三个库 并不是公用的cdn库,而是存在于我们本地项目中,所以还需要对三个组件进行单独打包出一个可用的组件.js,这样才能正常使用。这个配置入口应该是三个,对应三个组件,输出的规范应该也是commonjs2,因为我们的src/index.js就是使用import引入了三个组件

打包单个组件.js

entry:{
"button": "./packages/button.vue",
"select": "./packages/select.vue",
"checkbox": "./packages/checkbox.vue"
},
output: {
    path: path.resolve(process.cwd(), './lib'),
    filename: '[name].js', // 通过[name]可以动态生成了button.js select.js
    libraryTarget: 'commonjs2'
}

最后,我们的打包命令实际是需要运行2个webpack配置,得到的文件一个是四个:comp.common.js以及三个组件名.js。那么通过webpack的tree shaking的能力,当我们使用局部引入的写法,最后生成的打包文件将只打包局部使用到的组件代码了。

​ 到此文本就结束了,希望对大家带来实际的经验帮助。下一期我们来聊聊webpack的运行原理,一起动手撸一个简易的webpack吧!

相关文章

  • webpack三招必杀技

    相信每个前端同学一定都使用过webpack,作为一个划时代的构建工具,却有很多同学对他的认识还停留在怎么改个hos...

  • 武将隐藏必杀技

    配置武将隐藏必杀技,最多可配置3个 属性说明 名字 武将名字 必杀技 必杀技ID,可以参考必杀技ID对照表

  • 物品必杀技配置

    属性说明 物品名字 物品名字 必杀技 必杀技ID,查看必杀技ID对照表

  • 睡觉前的一百种对话

    妈妈这个叫什么 神龙金刚 它的技是什么 必杀技 必杀技叫什么 神龙闪光剪 ****** 妈妈下次放假我想去爬山 好...

  • webpack 基本配置和使用

    webpack 安装 安装本地的 webpack webpack webpack-cli -D webpack可以...

  • 减肥必杀技

    呵呵!是不是很想知道是什么减肥必杀技吆?其实,减肥是没有必杀技的,减肥更没有捷径可言。 我虽然不是个特别成...

  • webpack入门解析

    webpack 一. 认识webpack 1.1. webpack介绍 什么是webpack? 这个webpack...

  • webpack基础配置

    webpack安装 安装本地的webpack webpack webpack-cli -D webpack可以进行...

  • 如何打造自己的知识框架并建立自己的个人品牌?---《颠覆平庸》小

    很多人想树立自己的个人品牌,但是个人品牌的树立需要很多条件。找到自己的“必杀技”作为招牌,同时如果这项“必杀技”还...

  • Dota记忆 第七十二章 最初的必杀技

    最初的必杀技 “难道,你们还有必杀技?” 许莹莹吃惊的看着林锐宇和迪哥。 “前几天,我发现了迪哥真正的强大,那种状...

网友评论

    本文标题:webpack三招必杀技

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