浅谈webpack对样式的处理
本文介绍了webpack对样式的处理,分享给大家,具体如下:
我们可以在js中引入样式文件
require('myStyle.css')
这时我们便需要引入相应的webpack loader来帮助我们解析这段代码。
css-loader搭配style-loader
首先,我们可以引入css-loader和style-loader来处理css的解析,其中,css-loader是用来解析css文件,style-loader是用来将css文件嵌入到js文件里
var path = require('path') module.exports = { context: path.join(__dirname, 'src') entry: './', module: { rules: [ { test: /\.css$/, include: [ path.join(__dirname, 'src') ], use: ['style-loader', 'css-loader'] } ] }, output: { path: path.join(__dirname, 'dist'), filename: '[name].bundle.[hash].js' } }
在上面的代码里,解析顺序是从右到左解析,先使用css-loader解析出css文件之后,再使用style-loader嵌入到js代码里。
如果你使用less来写样式的话,则需要先用less-loader来编译样式文件为css文件,再继续使用css-loader与style-loader。另外,loader加载器可以省略后面的-loader。所以上面的代码可以缩写成
module: { rules: [ { test: /\.css$/, include: [ path.join(__dirname, 'src') ], use: ['style', 'css', 'less'] } ] }
一般在测试环境里为了快点编译css,会用这种方式多一点,但是这样子编译出来的js文件会比较大,不大适合在生产环境里使用。
编译成单独的文件
上面的做法会把css和js打包在一起,减少实际请求的次数,但是由于编译出来的js文件比较大,浪费带宽。因此,我们使用extract-text-webpack-plugin插件,把css文件编译成独立的文件。我们就可以利用CDN把这个文件推送到节点服务器,或者根据视情况按需加载,进而优化客户请求链路,加速页面响应。
var path = require('path'), ExtractTextPlugin = require('extract-text-webpack-plugin') module.exports = { context: path.join(__dirname, 'src'), entry: './', module: { rules: [{ test: /\.css$/, include: [ path.join(__dirname, 'src') ], use: ExtractTextPlugin.extract({ fallback: 'style', use: 'css' }) }] }, output: { path: path.join(__dirname, 'dist'), filename: '[name].bundle.[hash].js' }, plugins: [ new ExtractTextPlugin('[name].css') ] }
通过上面的代码,我们使用extract-text-webpack-plugin插件处理src目录下所有的css文件,先使用css-loader插件解析出css代码,如果解析失败,使用style-loader插件解析,最终在dist目录下生成对应的js文件
兼容旧浏览器
以前我们写样式时,有些样式不同浏览器需要加不同的前缀,如-webkit-。现在有了构建工具,我们便不需要再去关注这些前缀了,构建工具会自动帮我们加上这些前缀。
对于webpack我们自然想到需要使用loader或者plugin来帮助我们做这些事情,查了下发现autoprefixer-loader已经废弃不再维护了,推荐使用posscss
postcss是用于在js中转换css样式的js插件,需要搭配其他插件一起使用,这点和babel6一样,本身只是个转换器,并不提供代码解析功能。
这里我们需要autoprefixer插件来为我们的样式添加前缀。首先下载该模块。
npm install -D autoprefixer
接着便可以配置webpack了
var autoprefixer = require('autoprefixer') module.exports = { ... module: { loaders: [ ... { { test: /\.css$/, loader: ExtractTextPlugin.extract(["css", "postcss"]) }, } ] }, 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; }
样式压缩
压缩代码我们可以使用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'] }), ... ] }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- C++11 Lambda表达汇总总结
- TensorFlow开发环境搭建(Ubuntu16.04+GPU+TensorFlow源码编译)
- C++虚析构函数解析
- C-SATS工程副总裁教你如何用TensorFlow分类图像 part1
- 帝国cms文章页调用当前文章URL如何操作?
- dedecms文章页调用地址(当前文章URL)如何操作?
- 饭团开通一周,3人学会了比特币操作
- Sample K算法
- C#读取“我的文档”等特殊系统路径及环境变量
- winform CheckedListBox实现全选/全不选
- 机器学习该如何入门
- dedecms建的网站如何去掉/index.html
- WPF ContextMenu的使用
- Json的序列化与反序列化以及乱入的k_BackingField
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Centos7安装PHP及Nginx的教程详解
- Flutter Image实现图片加载
- Centos7系统下搭建.NET Core2.0+Nginx+Supervisor环境
- CentOS7 LNMP+phpmyadmin环境搭建 第二篇LNMP环境搭建教程
- 详解Linux 下开发微信小程序安装开发工具
- Linux一个增强的截图及分享工具:ScreenCloud
- linux 命名管道实例详解
- 11个JavaScript代码重构最佳实践
- Linux中在不破坏磁盘的情况下使用dd命令
- Jexus开机自动启动配置方法
- 在 CentOS 7 中安装 MySQL 8 的教程详解
- Centos7.2 编译安装PHP7.0.2的步骤
- Linux系统下为Nginx安装多版本PHP
- Linux系统下多版本php共存的解决方案(超简单)
- 宝塔Windows面板的安装Discuz! Q方法