1. 模块(必须配置):CSS打包 —> style-loader、 css-loader
场景: 将CSS文件,通过 import
引入到JS中,webapck 运行会报错,为解决问题需安装并配置 css 方面的loader
目的: 将CSS代码,打包到JS中,减少文件个数 减少HTTP请求
style-loader: 处理css文件中的 url()
等,npm 中网址
css-loader: 将css插入到页面的 中,npm 中网址
重点注意: 配置时 style-loader
必须在 css-loader
前面
安装: npm install style-loader css-loader --save-dev
配置(写法一): 直接用use
// webpack.config.js 文件中配置如下
module: {
rules: [
{
test:/\.css$/,
use: ['style-loader','css-loader']
}
]
}
// webpack.config.js 文件中配置如下
module: {
rules: [
{
test:/\.css$/,
loader: ['style-loader','css-loader']
}
]
}
// webpack.config.js 文件中配置如下
module: {
rules: [
{
test:/\.css$/,
use:[
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
}
npm run build
2. 插件:CCC 分离 —> extract-text-webpack-plugin
场景: 某些团队要求,将 CSS代码 单独提取,但 webpack 官方并不建议这样做(webpack 认为CSS就应该打包到JavasScript当中以减少http的请求数);为应对团队需求,我们可使用 CSS分离插件 extract-text-webpack-plugin
依赖于:
安装: npm install extract-text-webpack-plugin style-loader css-loader --save-dev
配置:
// webpack.config.js 文件中配置如下:CSS 打包 并 分离
const extractTextPlugin = require("extract-text-webpack-plugin");
plugins: [
new extractTextPlugin("/css/index.css") // /css/index.css 是CSS分离后的路径,以 dist文件夹为根目录
]
module:{
rules: [{
test: /\.css$/,
use: extractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}]
}
打包: npm run build
;项目打包后,dist文件夹中就会出现 css文件夹(含分离出来的css文件)
隐藏的问题:图片路径有问题: extract-text-webpack-plugin
插件很容易将 CSS分离出来,但是路径并不正确
配置 publicPath 来解决路径问题: 相对路径 变为 绝对路径(正确的),这样速度也会更快
// webpack.config.js 文件中配置如下
var website ={
publicPath:"http://localhost:3000/"
}
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].js',
publicPath:website.publicPath // 配置公共路径
},
3. 模块、插件:CSS 添加CSS3属性前缀 —> postcss-loader 、autoprefixer
场景: 为了浏览器的兼容性,有时候我们必须加入 -webkit, -ms, -o, -moz
这些前缀,为了让CSS3的样式生效
postcss 的相关配置项文档
postcss-loader: (模块)添加 CSS3前缀
autoprefixer: (插件)添加 CSS3前缀
依赖于:
安装: npm install postcss-loader autoprefixer style-loader css-loader --save-dev
基础配置:
webpack.config.js
同级),建立一个 postcss.config.js
文件// postcss.config.js 文件中配置如下
module.exports = {
plugins: [
require('autoprefixer')
]
}
// webpack.config.js 文件中配置如下
module: {
rules: [{
test: /\.css$/,
use: [
{
loader: "style-loader"
}, {
loader: "css-loader",
options: {
modules: true
}
}, {
loader: "postcss-loader"
}
]
}]
}
npm install extract-text-webpack-plugin --save-dev
// webpack.config.js 文件中配置如下
const extractTextPlugin = require("extract-text-webpack-plugin");
plugins: [
new extractTextPlugin('/css/index.css'), // 分离CSS
]
module: {
rules: [{
test: /\.css$/,
use: extractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
'postcss-loader'
]
})
}]
}
4. 模块配置: LESS 的打包 和 分离 — less-loader
less-loader: 打包less 文件 (编译)
依赖于:
less 模块:使用Less,我们要首先安装Less的服务
style-loader 和 css-loader 这两个loader
安装: npm install less less-loader style-loader css-loader --save-dev
配置: (选项一)less打包后 不分离
// webpack.config.js 文件中配置如下
module: {
rules: [{
test: /\.less$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'less-loader'
}
]
}]
}
npm install extract-text-webpack-plugin --save-dev
// webpack.config.js 文件中配置如下
const extractTextPlugin = require("extract-text-webpack-plugin");
plugins: [
new extractTextPlugin('/css/index.css'), // 分离CSS
]
module: {
rules: [{
test: /\.less$/,
use: extractTextPlugin.extract({
use: [{
loader: "css-loader"
}, {
loader: "less-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}]
}
5. 模块配置: SCSS 的打包 和 分离 —> sass-loader
sass-loader: 打包scss 文件 (编译)
依赖于:
node-sass 模块
style-loader 和 css-loader 这两个loader
安装: npm install node-sass sass-loader style-loader css-loader --save-dev
配置: (选项一)sass打包后 不分离
// webpack.config.js 文件中配置如下
module: {
rules: [{
test: /\.scss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
}]
}
npm install extract-text-webpack-plugin --save-dev
// webpack.config.js 文件中配置如下
const extractTextPlugin = require("extract-text-webpack-plugin");
plugins: [
new extractTextPlugin('/css/index.css'), // 分离CSS
]
module: {
rules: [{
test: /\.scss$/,
use: extractTextPlugin.extract({
use: [{
loader: "css-loader"
}, {
loader: "sass-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}]
}
6. 插件配置: 净化 CSS代码 —> PurifyCSS-webpack 、 purify-css
场景: 随着项目的更新迭代,会出现一些冗余的CSS代码,并没有使用,这是需要净化CSS,去掉无用的CSS代码,减少代码体积
约束: 目前看来,净化CSS的插件,必须配合 插件 extract-text-webpack-plugin
使用
插件 Purifycss-webpack: 净化CSS的插件(清除没有使用的CSS)
依赖于:
purify-css: PurifyCSS-webpack
依赖于 purify-css
node全局对象 glob: 因为 需要同步检查 全局html模板
const glob = require('glob'); // webpack.config.js 文件中 引入node全局对象
const PurifycssPlugin = require("purifycss-webpack"); // 引入插件
安装: npm install purifycss-webpack purify-css --save-dev
配置:
// webpack.config.js 文件中 配置如下
plugins: [
new PurifycssPlugin({ // 净化 CSS
paths: glob.sync(path.join(__dirname, 'src/*.html')),
})
]
1. 模块(必须配置):HTML / CSS 中 图片转码、打包后的路径转化 —> url-loader 、file-loader
场景: CSS文件中,给标签引入背景图片,webpack打包,终端报错
file-loader: 解决路径引用问题,【不限于解决CSS中的路径】 我们都知道,webpack最终会将多个文件,打包成一个文件,源码中的路径是相对路径,打包后需要根据打包结果调整资源路径,file-name
就是解决这个问题的
url-loader: 优化图片形式(优化性能)、解决路径问题。url-loader提供了一个limit参数,小于这个大小的图片,会被编码成 dataURl(Base64格式),相当于把图片数据翻译成一串字符,这样便可以减少HTTP资源请求,优化性能;大于limit参数的图片,会使用 file-loader 进行 copy(路径转换)
安装: npm install file-loader url-loader --save-dev
配置url-loader:
// webpack.config.js 文件中配置如下
module: {
rules: [{
test:/\.(png|jpg|gif)/ ,
use:[{
loader:'url-loader',
options:{
limit:500000, // 小于500000B 的图片打成Base64的格式,写入JS
outputPath: '/images/' // 大于500000B 的图片输出路径(将图片统一输出到一个文件夹中)
}
}]
}
]
}
打包: npm run build
疑问:为什么只使用了 url-loader ?
关系:url-loader 中封装(内置)了 file-loader
实际上,我们可以看出,url-loader 有两种作用
文件大小小于limit参数: 图片转码, url-loader将会把文件转为DataURL(Base64格式)
文件大小大于limit参数: 打包后的路径转化, url-loader会调用file-loader进行处理,参数也会直接传给file-loader
其实我们只安装一个url-loader就可以了。但是为了以后的操作方便,我们这里就顺便安装上 file-loader
2. 模块(必须配置):HTML 中 的处理 —> html-withimg-loader
场景: webpack 不建议使用 标签 来引入图片,它建议所有图片都使用背景图方式;若在html中使用
,打包后
标签的路径 及 引入的图片,不会被处理,使用
html-withimg-loader
这个 loader 可解决 html中引入 的问题(国人开发的 loader)
安装: npm install html-withimg-loader --save-dev
配置:
// webpack.config.js 文件中配置如下
module: {
rules: [{
test: /\.(htm|html)$/i,
use:[{
loader: 'html-withimg-loader'
}]
}]
}
npm run build
1. 插件配置:JS压缩 —> uglifyjs-webpack-plugin
webpack 内部集成插件 uglifyjs-webpack-plugin
,无需安装
配置:
// webpack.config.js 文件中配置如下
const uglify = require('uglifyjs-webpack-plugin');
plugins: [
new uglify()
]
2. 模块配置:babel 转化
场景: 前端开发中,ES6、ES7语法已盛行,但一些浏览器对 ES6 、ES7 语法不完全支持,为兼容所有浏览器,JS代码在部署时需要将 ES6、ES7 转为 浏览器支持的语法
Babel是什么? 一个 JavaScript 语法的编译器,可做到但不限于如下:
ECMAScript 语法转换
使用基于JavaScript进行了扩展的语言,比如React的JSX,转为 JS语法
编译不同的 JS,需要安装不同的 npm依赖包 详细见官网 / bebel中文网
模块:babel-loader
依赖于:
babel-core: babel的核心模块,需要单独安装
以下 选一个安装即可:
babel-preset-env:
env
babel-preset-es2015:
es2015
babel-preset-react:
react
需求: 将 ES6、ES7 转为兼容代码
安装: npm install babel-loader babel-core babel-preset-env --save-dev
配置:
// webpack.config.js 文件中配置如下
module: {
rules: [{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['env']
}
}
],
exclude: /node_modules/ // 屏蔽掉的文件
}]
}
配置优化: (可选)
项目一般都使用这种方式,配置 babel
考虑到 babel 有很多配置项,优化:在项目的根目录下,新建 .babelrc
文件,将 babel 配置项 统一写在 .babelrc
文件中
.babelrc 配置参考
// webpack.config.js 文件中配置如下
module: {
rules: [{
test: /\.js$/,
use: ['babel-loader'],
exclude: /node_modules/
}]
}
// .babelrc 文件中配置 如下:
// 还需要安装 babel-preset-stage-0 babel-plugin-transform-runtime babel-plugin-transform-remove-console
{
"presets": [
["env", { "modules": false }],
"stage-0" // stage-0 其实包含了 stage-[1-3] ,表示 state-0 及以上阶段的语法都会被转换,设置 state-0 也是最全面的babel转换设置
],
"plugins": [
"transform-runtime", // 来处理全局函数和优化babel编译
"transform-remove-console" // 编译后的代码都会移除console.*
],
"comments": false // 注释不被打包进去
}
demo 功能 说明
实现功能:
HTML、JS 、CSS 、LESS 、SCSS 代码 的编写、打包
图片的使用(HTML 中 img
标签的使用、CSS 中背景图的使用)
CSS 、LESS、SCSS 的前缀(不含:分离、净化,这个中能可配置)
JS 代码 的 打包、babel 转化(不含压缩 JS,这个功能了配置)
本地服务热更新(启动本地服务后,修改代码,页面自动刷新)
未实现功能:
demo 结构 说明
src 文件夹 (新建):开发环境的代码
dist 文件夹 (不用自己建,打包后自动生成):生产环境的代码
node_modules 文件夹 (自动生成):存放 项目的依赖模块
webpack.config.js 文件 (新建):webpack 配置文件
package.json 文件 (npm init
后自动生成):项目描述文件
postcss.config.js 文件(新建):通过此文件 配置 postcss
.babelrc 文件 (新建):babel-loader
配置中的 option
选项,单独写在此文件中
相关代码
package.json
文件:{
"name": "webpack-middle",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"server": "webpack-dev-server"
},
"author": "",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^8.1.0",
"css-loader": "^0.28.10",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^2.30.1",
"html-withimg-loader": "^0.1.16",
"less": "^3.0.1",
"less-loader": "^4.0.6",
"node-sass": "^4.7.2",
"postcss-loader": "^2.1.1",
"sass-loader": "^6.0.7",
"style-loader": "^0.20.2",
"url-loader": "^1.0.1",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.11.1",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.1",
"babel-plugin-transform-remove-console": "^6.9.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-stage-0": "^6.24.1"
},
"dependencies": {
}
}
webpack.config.js
文件:const glob = require('glob');
const path = require('path');
const htmlPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [{
test: /\.css$/,
use: [{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: "postcss-loader"
}
]
},
{
test: /\.less$/,
use: [{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'less-loader'
}
]
},
{
test: /\.scss$/,
use: [{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|jpg|gif)/,
use: [{
loader: 'url-loader',
options: {
limit: 500000,
outputPath: '/images/'
}
}]
},
{
test: /\.(htm|html)$/i,
use: [{
loader: 'html-withimg-loader'
}]
},
{
test: /\.js$/,
use: ['babel-loader'],
exclude: /node_modules/
}
]
},
plugins: [
new htmlPlugin({
minify: {
removeAttributeQuotes: true
},
hash: true,
template: './src/index.html'
})
],
devServer: {
contentBase: path.resolve(__dirname, 'dist'), // 服务文件路径
compress: true, // 启动服务压缩
host: 'localhost',
port: 2000
}
}
postcss.config.js
文件:// postcss 的相关配置
module.exports = {
plugins: [ // 引入插件
require('autoprefixer')
]
}
.babelrc
文件:{
"presets": [
["env", { "modules": false }],
"stage-0" // stage-0 其实包含了 stage-[1-3] ,表示 state-0 及以上阶段的语法都会被转换,设置 state-0 也是最全面的babel转换设置
],
"plugins": [
"transform-runtime", // 来处理全局函数和优化babel编译
"transform-remove-console" // 编译后的代码都会移除console.*
],
"comments": false // 注释不被打包进去
}