webpack多页运用架构系列(五):据说webpack连less/css也能打包?

本文首发于
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/indexindex/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)

附系列文章目次(同步更新)

本文首发于
Array_Huang的手艺博客——
有用至上,非经作者赞同,请勿转载。

原文地点:
https://segmentfault.com/a/1190000006897458

假如您对本系列文章感兴趣,迎接关注定阅这里:
https://segmentfault.com/blog/array_huang

    原文作者:array_huang
    原文地址: https://segmentfault.com/a/1190000006897458
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞