webpack实用配置解析

KernelDev
• 阅读 1478

相信每个前端同学一定都使用过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中,jquery我们可以放在CDN引用 但是如果这是一个本地库,那就必须使用webpack抽离第三方库的功能了。下面就用webpack帮我们实现这个功能。本案例中webpack版本是4.3,webpack4对于抽离第三库的功能已经集成了该功能,我们只需要用到optimization.splitChunks属性即可,不需要额外安装插件。

optimization: {

splitChunks: {  //分割代码块

cacheGroups: {  //缓存组 缓存公共代码

commons: {  //公共模块

name: "commons",

chunks: "initial",  //入口处开始提取代码

minSize: 0,      //代码最小多大,进行抽离

minChunks: 2,    //代码复 2 次以上的抽离

}

}

}

}

通过以上这个设置,最终输出的文件讲会把公用库抽离作为我们设置的commons.js【319k】 a.js和b.js就只有7k了

场景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吧!

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
storybook配置之基本配置和webpack配置
默认配置Storybook有一个默认的适合(suits)大型项目开发的webpack配置,假如你使用reactapp,他类似于创建一个reactapp的配置,并经过调整(tweaked),使其与vuecli的webpack配置非常相似开始学习Storybook配置学习内容(TableofContents)BabelES2016
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Stella981 Stella981
3年前
Linux菜鸟到老鸟的那些建议
相信很多同学对Linux(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.linuxprobe.com%2Fchapter00.html)的认识并不多,平常接触的也不多,对Linux的开发运维等也是一无所知。如今,如果要做一名优秀的程序猿,掌握Linux知识已经是一门必备技能了
可莉 可莉
3年前
18个常用 webpack插件,总会有适合你的!
!(https://oscimg.oschina.net/oscnet/71317da0c57a8e8cf5011c00e302a914609.jpg)来源| https://github.com/Michaellzg/myarticle/blob/master/webpack/Plugin何为插
Wesley13 Wesley13
3年前
KO
KOKO是一个基于Webpack开发的快速开始Web开发的脚手架工具,具有以下特性:可以当做一个Webpack配置种子来使用,无需二次配置、开箱即用自动支持多页应用(可选)Vue单文件组件的开发方式资源分块加载,内联和异步加载方式管理,低成本实现首屏优化支
京东云开发者 京东云开发者
11个月前
【黄金圆环】在研发领域的实践分享
这是我参与创作者计划的第1篇文章一、引言在前端开发中,构建工具的选择和使用至关重要。Webpack一直是前端构建工具的主流选择,但随着前端技术的发展,Vite作为一种新兴的构建工具,以其快速的开发体验和现代化特性,逐渐受到开发者的青睐。本文将结合黄金圆环法
京东云开发者 京东云开发者
6个月前
【黄金圆环】在研发领域的实践分享
作者:京东科技屠永涛这是我参与创作者计划的第1篇文章一、引言在前端开发中,构建工具的选择和使用至关重要。Webpack一直是前端构建工具的主流选择,但随着前端技术的发展,Vite作为一种新兴的构建工具,以其快速的开发体验和现代化特性,逐渐受到开发者的青睐。