先整理一波以前和webpack相关的文章:javascript
继以上第三篇文章后很大程度上提升了CSS的开发效率,可是仍存在如下遗留问题:css
为了下降和以前文章的耦合度,还有部分更新内容,故从新进行配置,和本文相关的内容会进行注释,其余配置的相关内容能够参考以上文章。html
+ 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属性及其配置的说明。java
<!DOCTYPE html> <html lang="zh-CN"> <head> <% /* 根据webpack.config.js中的title设置标题 */ %> <title><%= htmlWebpackPlugin.options.title %></title> <% /* 因为我的需求,不须要插入js,只须要css */ %> <% for (var css in htmlWebpackPlugin.files.css) { %><link href="<%=htmlWebpackPlugin.files.css[css] %>" rel="stylesheet"><% } %> </head> <body> <% /* html中使用到的图片需以以下方式插入,才可进行图片的一系列处理 */ %> <img src="<%=require('./images/home_bg.jpg')%>" alt="" style="width: 100px;"> </body> </html>
npm start