webpack使用总结
我们可以在js中引入样式文件
require('myStyle.css')
这时我们便需要引入相应的webpack loader来帮助我们解析这段代码。
一般来说需要引入css-loader和style-loader,其中css-loader用于解析,而style-loader则将解析后的样式嵌入js代码。
// webpack配置如下
{
module: {
loaders: [
{ test: /\.$/, loader: "style-loader!css-loader" }
]
}
}
可以发现,webpack的loader的配置是从右往左的,从上面代码看的话,就是先使用css-loader之后使用style-loader。
同理,如果你使用less来写样式的话,则需要先用less-loader来编译样式文件为css文件,再继续使用css-loader与style-loader。
{
module: {
loaders: [
{ test: /\.$/, loader: "style-loader!css-loader!less-loader" }
]
}
}
我们知道,webpack配置loader时是可以不写loader的后缀明-loader,因此css-loader可以写为css。
将样式抽取出来为独立的文件
将require引入的样式嵌入js文件中,有好处也有坏处。好处是减少了请求数,坏处也很明显,就是当你的样式文件很大时,造成编译的js文件也很大。
我们可以使用插件的方式,将样式抽取成独立的文件。使用的插件就是extract-text-webpack-plugin
基本用法如下
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
module: {
loaders: [
{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }
]
},
plugins: [
new ExtractTextPlugin("styles.css")
]
}
根据插件在github上的解释,ExtractTextPlugin.extract可以有三个参数。
第一个参数是可选参数,传入一个loader,当css样式没有被抽取的时候可以使用该loader。
第二个参数则是用于编译解析的css文件loader,很明显这个是必须传入的,就像上述例子的css-loader。
第三个参数是一些额外的备选项,貌似目前只有传入publicPath,用于当前loader的路径。
那什么时候需要传入第一个参数呢,那就得明白什么时候样式不会被抽取出来。
了解过code splittiog的同学便会知道,我们有些代码在加载页面的时候不会被使用时,使用code splitting,可以实现将这部分不会使用的代码分离出去,独立成一个单独的文件,实现按需加载。
那么如果在这些分离出去的代码中如果有使用require引入样式文件,那么使用ExtractTextPlugin这部分样式代码是不会被抽取出来的。
这部分不会抽取出来的代码,可以使用loader做一些处理,这就是ExtractTextPlugin.extract第一个参数的作用。
根据上面的案例,ExtractTextPlugin需要配合plugin使用。
new ExtractTextPlugin([id: string], filename: string, [options])
- 该插件实例的唯一标志,一般是不会传的,其自己会生成。
- 文件名。可以是[name]、[id]、[contenthash]
[name]:将会和entry中的chunk的名字一致
[id]:将会和entry中的chunk的id一致
[contenthash]:根据内容生成hash值 - options
allchunk: 是否将所有额外的chunk都压缩成一个文件
disable:禁止使用插件
这里的参数filename里如何理解呢?上述案例指定了一个固定的名字,因此便会生成一个styles.css文件。
那么像[name]、[id]这些如何理解。这个在你有多个entry的时候,便需要使用这种方式来命名。
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: {
"script": "./src/entry.js",
"bundle": "./src/entry2.js",
},
...
module: {
loaders: [
{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }
]
},
plugins: [
new ExtractTextPlugin("[name].css")
]
}
这时候便会生成两个css文件,一个是script.css,另一个便是bundle.css。那些[id]、[contenthash]也是一个道理。
只要明白,在你有多个entry是,一定要使用这种方式来命名css文件。
最后还有那个allchunks又是什么呢?很简单,还记得前面提到的code splitting么?将该参数配置为true,那么所有分离文件的样式也会全部压缩到一个文件上。
plugins: [
new ExtractTextPlugin("[name].css", {allChunks: true})
]
postcss
以前我们写样式时,有些样式不同浏览器需要加不同的前缀,如-webkit-。现在有了构建工具,我们便不需要再去关注这些前缀了,构建工具会自动帮我们加上这些前缀。
对于webpack我们自然想到需要使用loader或者plugin来帮助我们做这些事情,查了下发现autoprefixer-loader已经废弃不再维护了,推荐使用posscss
postcss是用于在js中转换css样式的js插件,需要搭配其他插件一起使用,这点和babel6一样,本身只是个转换器,并不提供代码解析功能。
这里我们需要autoprefixer插件来为我们的样式添加前缀。首先下载该模块。
npm install autoprefixer --save-dev
接着便可以配置webpack了
var autoprefixer = require('autoprefixer')
module.exports = {
...
module: {
loaders: [
...
{
{
test: /\.css$/,
loader: ExtractTextPlugin.extract(["css-loader", "postcss-loader"])
},
}
]
},
postcss: [autoprefixer()],
...
}
查看一下抽取出来的样式文件便可以发现已经加上了前缀
a {
display: flex;
}
/*compiles to:*/
a {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex
}
另外autoprefixer还可以根据目标浏览器版本生成不同的前缀个数,例如你的应用的使用用户如果大多数是使用比较新版本的浏览器,那么便可以做如下配置。
postcss: [autoprefixer({ browsers: ['last 2 versions'] })]
这是生成的样式便会有些不一样,还是上面的例子
a {
display: flex;
}
/*compiles to:*/
a {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
postcss后记
这里再说一个问题,有些童鞋可能会在css文件中使用@import引入其他样式文件,但是使用autoprefixer发现,import进来的样式没有处理,如下面所示:
/*myStyle.css:*/
body {
padding: 0px; line-height: 1.5;">gray;
}
.flex {
display: flex;
} /*myStyle2.css:*/
@import "./myStyle.css";
.div {
color: red;
} /*autoprefixer之后*/
body {
padding: 0px; line-height: 1.5;">gray;
}
.flex {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
body {
padding: 0px; line-height: 1.5;">gray;
}
.flex {
display: flex;
}
.div {
color: red;
}
要解决这个问题,postcss有个解释,它让我们使用postcss-import插件,再配合autoprefixer
postcss: function(webpack) {
return [
postcssImport({
addDependencyTo: webpack
}),
autoprefixer
]
},
其实我们是不推荐使用@import的,心细的童鞋可以看到最后生成的样式文件有样式是重复的。
所以一般我们应该是在js中使用require来引入样式文件。可以参考的说法这里
样式压缩
压缩代码我们可以使用webpack的内置插件UglifyJsPlugin来做,它既可以压缩js代码也可以压缩css代码。
plugins: [
...
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
...
]
其实并不能说是在压缩css代码,本质来说还是压缩js代码,再将这块代码输出到css文件中。
使用CommonsChunkPlugin抽取公共代码
首先要明确一点CommonsChunkPlugin是在有多个entry时使用的,即在有多个入口文件时,这些入口文件可能会有一些共同的代码,我们便可以将这些共同的代码抽取出来成独立的文件。明白这一点非常重要。(搞了很久才明白的一点,唉~~~~)
如果在多个entry中require了相同的css文件,我们便可以使用CommonsChunkPlugin来将这些共同的样式文件抽取出来为独立的样式文件。
module.exports = {
entry: {
"A": "./src/entry.js",
"B": "./src/entry2.js"
},
...
plugins: [
new webpack.optimize.CommonsChunkPlugin({name: "commons", filename: "commons.js"}),
...
]
}
当然,这里不止会抽取共同的css,如果有共同的js代码,也会抽取成为commons.js。
这里有个有趣的现象,抽取出来的css文件的命名将会是参数中name的值,而js文件名则会是filename的值。
CommonsChunkPlugin好像只会将所有chunk中都共有的模块抽取出来,如果存在如下的依赖
// entry1.js
var style1 = require('./style/myStyle.css')
var style2 = require('./style/style.css') // entry2.js
require("./style/myStyle.css")
require("./style/myStyle2.css") // entry3.js
require("./style/myStyle2.css")
使用插件后会发现,根本没有生成commons.css文件。
如果我们只需要取前两个chunk的共同代码,我们可以这么做
module.exports = {
entry: {
"A": "./src/entry.js",
"B": "./src/entry2.js",
"C": "./src/entry3.js"
},
...
plugins: [
new webpack.optimize.CommonsChunkPlugin({name: "commons", filename: "commons.js", chunks: ['A', 'B']}),
...
]
}
补充一下
根据webpack官网中关于stylesheet的说法,建议是不要将allChunks设为true,即只是将样式嵌入到分离文件中。
这个可能还是需要具体问题具体分析了。
webpack使用总结的更多相关文章
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- webpack之傻瓜式教程
接触webpack也有挺长一段时间了,公司的项目也是一直用着webpack在打包处理,但前几天在教新人的情况下,遇到了一个问题,那就是:尽管网上的webpack教程满天飞,但是却很难找到一个能让新人快 ...
- 细说前端自动化打包工具--webpack
背景 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过链接组织在一起.用过Dreamweaver的都知道,做网页就像用word编辑文档 ...
- Webstorm+Webpack+echarts构建个性化定制的数据可视化图表&&两个echarts详细教程(柱状图,南丁格尔图)
Webstorm+Webpack+echarts ECharts 特性介绍 ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(I ...
- 使用webstorm+webpack构建简单入门级“HelloWorld”的应用&&引用jquery来实现alert
使用webstorm+webpack构建简单入门级"HelloWorld"的应用&&构建使用jquery来实现 1.首先你自己把webstorm安装完成. 请参考这 ...
- webpack入门教程之Hello webpack(一)
webpack入门教程系列为官网Tutorials的个人译文,旨在给予想要学习webpack的小伙伴一个另外的途径.如有不当之处,请大家指出. 看完入门教程系列后,你将会学习到如下内容: 1.如何安装 ...
- webpack的使用
1.webpack是什么? 打包前端项目的工具(为项目提高逼格的东西). 2.webpack的基本命令 webpack#最基本的启动webpack命令 webpack-w #提供watch方法,实时进 ...
- Webpack 配置摘要
open-browser-webpack-plugin 自动打开浏览器 html-webpack-plugin 通过 JS 生成 HTML webpack.optimize.UglifyJsPlugi ...
- Vue + Webpack + Vue-loader 系列教程(2)相关配置篇
原文地址:https://lvyongbo.gitbooks.io/vue-loader/content/ 使用预处理器 在 Webpack 中,所有的预处理器需要和一个相应的加载器一同使用.vue- ...
- Vue + Webpack + Vue-loader 系列教程(1)功能介绍篇
原文地址:https://lvyongbo.gitbooks.io/vue-loader/content/ Vue-loader 是什么? vue-loader 是一个加载器,能把如下格式的 Vue ...
随机推荐
- 关于post与get请求参数存在特殊字符问题
遇到项目中存在文本编辑框输入特殊字符 比如:# ? & 空格 , 导致后台接受不到参数问题,对可能存在特殊字符的参数进行encodeURIComponent; C#后台接受参数不需要解码 也可 ...
- ICMP(网际控制报文协议)
为了更有效的提高ip数据报的成功转发和交付的效率,在网际层使用了icmp网际控制报文协议,这个协议允许主机和路由器提供差错和异常情况的报告,icmp不是高层协议,而是网际层的协议,加在ip数据报中一起 ...
- 一篇知乎的故事 - javascript技术贴
前言 就像文章题目所示,本文的发表源于知乎的一篇文章.文章链接如下:如果你想靠前端技术还房贷,你不能连这个都不会.这篇文章是群里水群时别人发的,像我这样的菜鸟角色才不会逛知乎~~~.这篇文章主要是讲了 ...
- 剑指offer编程题Java实现——替换空格
题目描述 请实现一个函数,将一个字符串中的空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. package ...
- SecureCRT文件传输模式
前言 如下图所示,SecureCRT6.5.0 有4种文件传输模式. 1)ASCII:最快的传输模式,但只能传文本 2)Xmodem:非常古老的传输协议速度较慢,但由于使用了CRC错误侦测方法,传输的 ...
- storm 1.0版本滑动窗口的实现及原理
滑动窗口在监控和统计应用的场景比较广泛,比如每隔一段时间(10s)统计最近30s的请求量或者异常次数,根据请求或者异常次数采取相应措施.在storm1.0版本之前,没有提供关于滑动窗口的实现,需要开发 ...
- 每天一个linux命令(47)--scp命令
scp是secure copy 的简写,用于在Linux 下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝而不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当 ...
- ios的300ms点击延时问题
一.什么是ios的300ms点击延时问题 ios的移动端页面对点击事件有300ms延时. 二.为什么存在这个问题 这要追溯至 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题 —— ...
- PHP控制反转(IOC)和依赖注入(DI)
先看一个例子: <?php class A { public $b; public $c; public function A() { //TODO } public function Meth ...
- TCP和UDP 的区别和适用场合
TCP和UDP式TCP/IP中能够实现传输层功能的.具有代表性的协议,其主要特点和区别如下: TCP: 面向连接的.可靠的流协议.为提供可靠性传输,TCP实行"顺序控制"或&quo ...