改编自微信公众号:前端js动力节点。
webpack这个单词,我们可以拆开来读:web、pack。
pack是啥意思?打包,对吧?
所以webpack的核心就是打包,将所有的资源全部打包压成一个个模块,就像酱紫滴:
我们这节课重点讲一下css的打包。
有同学就犯嘀咕了:
你说js打包我还能理解,而css打包是个什么卵?css还用打包?开什么国际玩笑?
这种质疑不无道理。
因为从传统观点来看,css生下来就是个二等公民。js开始也是个二流货色,但经过这几年的努力,人家已经洗白白成了白富美;而css呢,好容易折腾到css3,虽然整了容,变的漂亮了些,但仍不登大雅之堂,不受人待见。
大家都是二等公民出身,为啥你js能起来,我就不行?css心中一万头草泥马奔过,难道这就是命运的安排?
人贵在有自知之明。当人生遇到低谷,最重要的是反思自己,而不是跟个怨妇一样抱怨。
css为啥无法成为白富美?
首先,可能是因其语法简单,没有什么挑战性;其次,大家也不怎么重视css的规范性。在传统模式下,css都是一股脑写在一个大文件里,然后加载到网页的,这样就直接导致了管理上的混乱:
在css增量开发时,要时刻注意命名空间问题;到了调试阶段,又不得不依赖谷歌控制台或firebug的元素定位,有时父类的某个属性影响了子类,导致修改子类样式无法达到预期。。。。
自从有了react和vue,css的灵魂得到了救赎。这两种框架均提出组件化编程的思想,也就是将html,css,js均凝聚成一个不可分割的小部件,留出对外通信的接口,然后灵活组合使用,譬如下图所示:
这样一来,css就有了打包的可能性。打包的好处是:
css也有了模块化,可以不用再关心命名空间问题,只需专心将这个部件渲染好,出了问题也更容易定位追踪。
知其然知其所以然,我们搞懂了为啥css要打包的道理,下面就可以愉快而主动的学习了。
仔细权衡了一下,这里我并不打算引入react或vue讲解,因为这样会增加大家理解上的负担。学习新东西,最忌讳的就是学了这个又牵扯到那个,结果精力分散重点转移,到最后很可能一个都没搞懂,还增加了自己的挫败感。
为了简单起见,我们仍旧沿用前面那个案例做讲解,先把这个webpack玩转再说。
咱们看一下具体玩法。首先还是安装插件,这里我们需要两个工具:
npm install style-loader npm install css-loader
原料有了,我们做一下测试文件做测试。我们首先新建一个style.css文件,目录结构如下:
style.css:
.content { color: red; }
很简单,就是一个样式类。然后我们改一下helloworld.js文件。
helloworld.js:
// 引入css模块 var styles = require('../style.css'); // 输出模块 module.exports = () => { // 这里使用了箭头函数,还有let和const关键字哦~~ let content = "Hello "; const NAME = "ES6"; var div = document.createElement('div'); div.setAttribute('class', styles.content); // 使用样式类 div.innerHTML = content + NAME; return div; };
注意,这里跟我们平时写的有点不一样。
我们在建一个dom节点时,指定了一个样式类。但是这个样式类,是以包的形式存在的,也就是一个模块。
综合起来看我们这个helloworld.js模块,是不是把html,css和js凝聚成了一个小整体了呢?
我知道你已经迫不及待的想看结果了,好吧,咱们赶紧写一下配置文件跑起来吧~~
webpack.config.js:
var path = require('path'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: ['env'] } }, { test: /\.css$/, loader: 'style-loader!css-loader?modules' }] } };
说明:
style-loader和css-loader是工具名称。
!感叹号是分割符,表示两个工具都参与处理。
?问号,其实跟url的问号一样,就是后面要跟参数的意思。
而modules这个参数呢,就是将css打包成模块。跟js打包是一样的,你不必再担心不同模块具有相同类名时造成的问题了。
我们运行一下:(我这次特地没在局部安装webpack-cli,发现可以运行,因为我昨天在全局安装了webpack-cli,之所以要在全局安装而单独局部安装不行,可能跟package.json有关,因为这里都没有用到package.json)。
如果不报错,我们打开浏览器,看一下index.html:
我们看到,样式已然生效了,但是我们打开控制台,看到class的名称并非是我们写的样式类.content,而是生成了新名称,这就说明webpack的编译生效了。
我们打开bundle.js看一下,css其实已经被打包编译到了bundle.js文件里:(太长,截了一部分)
我们看到,css打包后,存在形态已经变成了js。这没有什么可奇怪的,只有这样才能使用包的形式做管理,css本身,是无法达到这样的目的的,所以,它还是二等公民。。。。