本文首发于
Array_Huang的手艺博客——
有用至上
,非经作者赞同,请勿转载。原文地点:
https://segmentfault.com/a/1190000006897458
假如您对本系列文章感兴趣,迎接关注定阅这里:
https://segmentfault.com/blog/array_huang
媒介
过去讲前端模块化、组件化,更多照样停留在js层面,毕竟js作为一种更典范的程序语言,在这方面的设想和操纵空间都更大一些。但近年来,组件化要求得更多了,HTML/CSS/JS这三件套一件可都不能少(以至包括别的范例的资本,比方说图片),而如许的组件,无疑是高内聚
的。
文章简介
本文将引见怎样运用webpack来打包less/css(没用过sass,但毕竟也是经由过程loader来加载的,置信与less无异),起首是引见相干的webpack plugin&loader,然后将引见怎样加载差别运用条理的less/css。
用到什么loader了?
在《webpack多页运用架构系列(二):webpack设置经常使用部份有哪些?》里我就说过,webpack的中心只能打包js文件,而js之外的资本都是靠loader举行转换或做出响应的处置惩罚的。下面我就来引见打包less/css所须要的loader。
less-loader
针对less文件,我们起首须要运用less-loader来加载。less-loader会挪用所依靠的less
模块对less文件举行编译(包括@import
语法)。至于说less-loader所接收的参数,实质上大部份是传递给less
模块运用的参数,由于我本人运用less的水平不深,因而没有传任何参数、直接就运用了。假如你之前对less
模块就已经有了一套设置的话,请参考less-loader的文档举行设置。
别的,less-loader并不会针对url()
语法做迥殊的转换,因而,假如你想把url()
语句里涉及到的文件(比方图片、字体文件等)也一并用webpack打包的话,就必须应用管道交给css-loader做进一步的处置惩罚。
css-loader
针对css文件,我们须要运用css-loader来加载.css-loader的功用比较壮大,一些新鲜的特征比方Local Scope
或是CSS Modules
都是支撑的。
我现在只用到了css-loader的紧缩功用(Minification),关于这个功用,有一点是须要注重的,那就是假如你的代码里也和我一样,有许多为了浏览器兼容性的烧毁CSS代码的话,请务必封闭autoprefixer
已防止你的烧毁CSS代码被css-loader删除了,形如css?minimize&-autoprefixer
。
上面提到css-loader会对url()
语句做处置惩罚,这里轻微再说两句。在less/css里的这url()
语句,在css-loader看来,就跟require()
语句是一样的,只需在webpack设置文件里定义好加载各范例资本的loader,那这url()
语句实际上什么资本都能处置惩罚。平常我在url()
语句都邑以相对途径的体式格局(相关于此语句地点的less/css文件)来指定文件途径;请不要运用以/
开首(即相关于网站根目次,由于关于文件体系来讲,这显著是使人殽杂的)的途径,只管css-loader也能够经由过程设置root
参数来适配。
postcss-loader
习习用postcss的童鞋们有福啦,webpack能够经由过程postcss-loader来兼容postcss。由于postcss只算是一个加分项,因而这里也不作过量引见,只引见一下怎样把postcss撘进webpack,不明白的童鞋贫苦先把postcss搞懂了再看。
放上我的脚手架项目的代码:
var precss = require('precss');
var autoprefixer = require('autoprefixer');
module.exports = {
module: {
loaders: [
{
test: /\.css$/,
exclude: /node_modules|bootstrap/,
loader: 'css?minimize&-autoprefixer!postcss',
}
]
},
postcss: function () {
return [precss, autoprefixer({
remove: false,
browsers: ['ie >= 8', '> 1% in CN'],
})];
}
}
从loader的设置'css?minimize&-autoprefixer!postcss'
上看,实际上就是先让postcss-loader处置惩罚完了再传递给css-loader。而postcss
项则是postcss-loader所接收的参数,实际上就是返回一个包括你所须要的postcss’s plugins的数组啦,这些plugin有各自的初始化参数,不过这些都是postcss的内容了,这里就不做引见了。
用到什么Plugin了?
加载less/css这一块重要用到的是extract-text-webpack-plugin
(下文简称为ExtractTextPlugin
吧),而且由于我用的是webpack 1
,因而用的也是相对应webpack 1
的版本(1的文档在这里不要搞错了哈)。
ExtractTextPlugin的作用是把各个chunk加载的css代码(多是由less-loader转换过来的)合并成一个css文件并在页面加载的时刻以<link>
的情势举行加载。
相关于运用style-loader直接把css代码段跟js打包在一同并在页面加载时以inline的情势插进去DOM,我照样更喜好ExtractTextPlugin天生并加载CSS文件的情势;倒不是看不惯inline的css,只是用文件情势来加载的话会快许多,特别背面引见用webpack来天生HTML的时刻,这<link>
会直接天生在<head>
里,那末在CSS的加载上就跟传统的前端页面没有差别了,体验异常棒。
ExtractTextPlugin的初始化参数不多,唯一的必填项是filename
参数,也就是怎样来定名天生的CSS文件。跟webpack设置里的output.filename参数相似,这ExtractTextPlugin的filename参数也许可运用变量,包括[id]、[name]和[contenthash];理论上来讲假如只需一个chunk,那末不必这些变量,写死一个文件名也是能够的,但由于我们要做的是多页运用,必定存在多个chunk(最少每一个entry都对应一个chunk啦)。这里我是这么设置的:
new ExtractTextPlugin('[name]/styles.css'), // [name]对应的是chunk的name,我在webpack设置中是如许
[name]
对应的是chunk的name,我在webpack设置中把各个entry的name都按index/index
、index/login
如许的情势来设置了,那末末了css的途径就会像如许:build/index/index/styles.css
,也就是跟chunk的js文件放一块了(js文件的途径形如build/index/index/entry.js
)。
除了要把这初始化后的ExtractTextPlugin放到webpack设置中的plugins
参数里,我们还要在loader设置里做响应的修正:
module.exports = {
module: {
loaders: [
{
test: /\.css$/,
exclude: /node_modules|bootstrap/,
loader: ExtractTextPlugin.extract('css?minimize&-autoprefixer!postcss'),
}
]
},
}
如此一来,ExtractTextPlugin就算是设置好了。
怎样加载差别运用条理的less/css
在我的设想中,有三种运用条理的less/css代码段:
- 基本的、公用的代码段,包括CSS框架、在CSS框架上举行定制的CSS theme,基本上每一个页面都邑运用到这些CSS代码段。
- 组件的代码段,这里的
组件
指的是你自身写的组件,而且组件自身含有js,并担任加载css以及别的逻辑。 - 每一个页面独占的CSS代码段,极能够只是对某些细节举行微调。
起首来回忆一下我设想的文件目次构造:
├─src # 当前项目的源码
├─pages # 各个页面独占的部份,如进口文件、只需该页面运用到的css、模板文件等
│ ├─alert # 营业模块
│ │ └─index # 详细页面
│ ├─index # 营业模块
│ │ ├─index # 详细页面
│ │ └─login # 详细页面
│ │ └─templates # 假如一个页面的HTML比较复杂,能够分红多块再拼在一同
│ └─user # 营业模块
│ ├─edit-password # 详细页面
│ └─modify-info # 详细页面
└─public-resource # 各个页面运用到的大众资本
├─components # 组件,能够是纯HTML,也能够包括js/css/image等,看自身须要
│ ├─footer # 页尾
│ ├─header # 页头
│ ├─side-menu # 侧边栏
│ └─top-nav # 顶部菜单
├─config # 种种设置文件
├─iconfont # iconfont的字体文件
├─imgs # 公用的图片资本
├─layout # UI规划,构造各个组件拼起来,因应须要能够有差别的规划套路
│ ├─layout # 详细的规划套路
│ └─layout-without-nav # 详细的规划套路
├─less # less文件,用sass的也能够,又或者是纯css
│ ├─base-dir
│ ├─components-dir # 假如组件自身不须要js的,那末要加载组件的css比较难题,我发起能够直接用less来加载
│ └─base.less # 构造一切的less文件
├─libs # 与营业逻辑无关的库都能够放到这里
└─logic # 营业逻辑
基本代码段
基本的CSS代码(实际上我的项目顶用的都是less)我一致都放到src/public-resource/less
目次里。我运用一个笼统的文件base.less
将一切的less文件构造起来(应用@import
),如许的话我用js加载起来就轻易多了。
在我的脚手架项目(Array-Huang/webpack-seed)里,CSS框架我用的是bootstrap,而且运用了bootstrap-loader举行加载,因而就没有把bootstrap的CSS文件放到src/public-resource/less/base-dir
目次里,这个目次里放的都是我定制的theme了。
src/public-resource/less/components-dir
目次放的是某些第三方组件所用到的css,又或是不含js的组件所用到的css。实在这部份CSS是不是应当归鄙人一类,我也斟酌很久,只是由于归到下一类的话加载起来不轻易,不轻易缘由以下:
- 某些第三方库是要你自身加载CSS的,假如你盘算写适配器来封装这些第三方库,那天然能够直接在适配器来加载CSS,这就属于下一类了;但是,有一些运用起来很简朴的库,你还写适配器那就有点弄巧成拙了。
- 某些自身写的组件能够仅包括HTML和CSS,那末谁来加载CSS?
所以痛快照样交由base.less
一并加载了算了。
我设想了一个common.page.js
,并在每一个页面的进口文件里都起首加载这common.page.js
,那末,只需我在这common.page.js
里加载base.less
,一切的页面都能享受到这份基本CSS代码段。
组件代码段
组件的代码我都放在了src/public-resource/components
,每一个组件一致放在一个自力的目次,并由该组件的js担任加载其CSS。
页面代码段
页面独占的CSS我天然是放在该页面自身的目次里,应用该页面的进口文件举行加载。
终究天生的CSS代码都在哪?
由于我运用了ExtractTextPlugin,因而这些CSS代码终究都邑天生到所属chunk的目次里成为一个CSS文件。
- 基本代码段肯定是保存在CommonsChunkPlugin所天生的大众代码chunk地点的目次里了,在我的脚手架项目(Array-Huang/webpack-seed)里就是
build/commons
了(我的大众代码chunk的name是’commons’)。 - 组件代码段看情况,该组件用的页面多的话(大于CommonsChunkPlugin的minChunks参数)就会被归到跟基本代码段一同咯;反之,则哪一个页面用到它,就放到哪一个页面chunk的目次里咯。
- 页面代码段就不必想了,肯定是在谁人页面chunk的目次里了,毕竟才用了1次。
示例代码
诸位看本系列文章,搭配我在Github上的脚手架项目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed
)。
附系列文章目次(同步更新)
- webpack多页运用架构系列(一):一步一步处理架构痛点:
https://segmentfault.com/a/1190000006843916
- webpack多页运用架构系列(二):webpack设置经常使用部份有哪些?:
https://segmentfault.com/a/1190000006863968
- webpack多页运用架构系列(三):怎样打包大众代码才防止反复?:
https://segmentfault.com/a/1190000006871991
- webpack多页运用架构系列(四):老式jQuery插件还不能丢,怎样兼容?:
https://segmentfault.com/a/1190000006887523
- webpack多页运用架构系列(五):据说webpack连less/css也能打包?:
https://segmentfault.com/a/1190000006897458
- webpack多页运用架构系列(六):据说webpack连图片和字体也能打包?:
https://segmentfault.com/a/1190000006907701
- webpack多页运用架构系列(七):开辟环境、临盆环境傻傻分不清楚?:
https://segmentfault.com/a/1190000006952432
- webpack多页运用架构系列(八):锻练我要写ES6!webpack怎样整合Babel?:
https://segmentfault.com/a/1190000006992218
- webpack多页运用架构系列(九):总有刁民想害朕!ESLint为你阻击渣滓代码:
https://segmentfault.com/a/1190000007030775
- webpack多页运用架构系列(十):怎样打造一个自定义的bootstrap:
https://segmentfault.com/a/1190000007043716
- webpack多页运用架构系列(十一):预打包Dll,完成webpack音速编译:
https://segmentfault.com/a/1190000007104372
- webpack多页运用架构系列(十二):应用webpack天生HTML一般网页&页面模板:
https://segmentfault.com/a/1190000007126268
- webpack多页运用架构系列(十三):构建一个简朴的模板规划体系:
https://segmentfault.com/a/1190000007159115
- webpack多页运用架构系列(十四):No复制粘贴!多项目共用基本设施
- webpack多页运用架构系列(十五):论前端怎样在后端衬着开辟形式下夹缝生计
- webpack多页运用架构系列(十六):善用浏览器缓存,该去则去,该留则留
本文首发于
Array_Huang的手艺博客——
有用至上
,非经作者赞同,请勿转载。原文地点:
https://segmentfault.com/a/1190000006897458
假如您对本系列文章感兴趣,迎接关注定阅这里:
https://segmentfault.com/blog/array_huang