原文地址:https://segmentfault.com/a/1190000021518323
作者:Fw恶龙
本文首发于:思否
先整理一波之前和webpack相关的文章:
继以上第三篇文章后很大程度上提高了CSS的开发效率,但是仍存在以下遗留问题:
为了降低和之前文章的耦合度,还有部分更新内容,故重新进行配置,和本文相关的内容会进行注释,其他配置的相关内容可以参考以上文章。
+ node_modules // npm install 生成
+ src // 开发目录(自行创建)
- index.ejs // 用于生成index.html的模板文件
+ css
- sprite.styl // webpack-spritesmith生成
- index.styl
- function.styl // styl个人常用函数
+ images
- sprite.png // webpack-spritesmith生成
+ sprite // 雪碧图放置文件夹
..png
..png
+ js
+ index.js
+ dist // 代码产出目录
– index.html // html-webpack-plugin生成
+ css
- index.css
+ images
- icon.png
+ js
- index.js
+ other
index.js
– package.json // npm init 生成
– package-lock.json // npm install 生成
- postcss.config.js // 自行创建
– webpack.config.js // 自行创建
npm init
{
"name": "cwwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack --mode development"
},
"author": "",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^9.1.2",
"clean-webpack-plugin": "^1.0.0",
"css-loader": "^1.0.0",
"cssnano": "^4.0.5",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^6.0.0",
"postcss-loader": "^3.0.0",
"postcss-sorting": "^4.0.1",
"stylus": "^0.54.5",
"url-loader": "^1.1.1",
"webpack": "^4.17.0",
"webpack-cli": "^3.1.2",
"webpack-spritesmith": "^0.5.4"
},
"dependencies": {
"mini-css-extract-plugin": "^0.4.1",
"stylus-loader": "^3.0.2"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8",
"ios >= 8",
"android >= 4.0"
]
}
npm install
var path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const SpritesmithPlugin = require('webpack-spritesmith');
const HtmlWebpackPlugin = require('html-webpack-plugin');
var templateFunctionStylSprite = function(data) {
var sharedRem = '.ico\n display: inline-block\n background-image: url("I")\n background-size: Dpx Hpx'
.replace('I', data.sprites[0].image)
.replace('D', data.sprites[0].total_width)
.replace('H', data.sprites[0].total_height);
var perSpriteRem = data.sprites.map(function(sprite) {
return '.ico-N\n width: Wpx\n height: Hpx\n background-position: Xpx Ypx'
.replace('N', sprite.name.replace(/_/g, '-'))
.replace('W', sprite.width)
.replace('H', sprite.height)
.replace('X', sprite.offset_x)
.replace('Y', sprite.offset_y);
}).join('\n');
return sharedRem + '\n' + perSpriteRem;
};
module.exports = {
entry: { // 入口文件,若有多个入口文件可以继续创建,用于解决前言中提到的第一点
'index': __dirname + "/src/js/index.js"
},
output: {
path: __dirname + "/dist", //打包后的文件存放的地方
filename: "js/other/[name].js" //打包后输出文件的文件名
},
watch: true, //开启自动编译
module: {
rules: [{
test: /\.styl$/,
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../"
}
}, {
loader: "css-loader"
}, {
loader: "postcss-loader"
}, {
loader: "stylus-loader"
}]
},
{
test: /\.(png|svg|jp?g|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8192,
name: 'images/[name].[ext]?v=[hash:8]'
}
}, {
loader: 'image-webpack-loader', // 图片压缩,用于解决前言中提到的第三点
options: {
mozjpeg: {
progressive: true,
quality: 90
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: true,
},
pngquant: {
quality: [0.90, 1.00],
speed: 4
},
gifsicle: {
interlaced: false,
}
}
}]
}
]
},
plugins: [
new CleanWebpackPlugin(
['dist/css', 'dist/images'],
{
root: __dirname,
verbose: true,
dry: true
}
),
new SpritesmithPlugin({
src: {
cwd: path.resolve(__dirname, 'src/images/sprite'),
glob: '*.png'
},
target: {
image: path.resolve(__dirname, 'src/images/sprite.png'),
css: [
[path.resolve(__dirname, 'src/css/sprite.styl'), {
format: 'function_based_template'
}]
]
},
customTemplates: {
'function_based_template': templateFunctionStylSprite
},
apiOptions: {
cssImageRef: '../images/sprite.png'
},
spritesmithOptions: {
algorithm: 'binary-tree',
padding: 2
}
}),
new MiniCssExtractPlugin({
filename: "css/[name].css?v=[hash:8]",
chunkFilename: "[id].css"
}),
new HtmlWebpackPlugin({ // 打包html文件,用于解决前言中提到的第二点
template:'./src/index.ejs', // 模板文件路径
filename: 'index.html', // 生成的文件名
title: 'My App', // 页面title
chunks: ['index'], // 需要引入的入口文件,根据entry的入口文件进行配置,会将其生成的css和js插入到模板中
inject: false, // 不插入生成的js文件,只是单纯的生成一个html文件,由于个人开发需求,js不需要引入,需要单独开发
minify:{ //压缩HTML文件,常用属性如下
removeComments: false, // 移除HTML中的注释
collapseWhitespace: false, // 删除空白符
preserveLineBreaks: false, // 删除换行
removeStyleLinkTypeAttributes: true, // type="text/css"从style和link标签中删除
removeScriptTypeAttributes: true // type="text/javascript"从script标签中删除
}
})
],
};
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano')({
preset: 'default',
}),
require('postcss-sorting')({
'properties-order': 'alphabetical'
})
]
}
import '../css/index.styl';
@import "function.styl"
@import "sprite.styl"
关于为何使用ejs后缀名,可以参考以下关于html-webpack-plugin属性及其配置的说明。
<% /* 根据webpack.config.js中的title设置标题 */ %>
<%= htmlWebpackPlugin.options.title %>
<% /* 由于个人需求,不需要插入js,只需要css */ %>
<% for (var css in htmlWebpackPlugin.files.css) { %><% } %>
<% /* html中使用到的图片需以如下方式插入,才可进行图片的一系列处理 */ %>
npm start
原文地址:https://segmentfault.com/a/1190000021518323