let ExtractTextPlugin = require('extract-text-webpack-plugin'); // multiple extract instances let extractCSS = new ExtractTextPlugin('stylesheets/[name].css'); let extractLESS = new ExtractTextPlugin('stylesheets/[name].less'); module.exports = { ... module: { loaders: [ {test: /\.scss$/i, loader: extractCSS.extract(['css','sass'])}, {test: /\.less$/i, loader: extractLESS.extract(['css','less'])}, ... ] }, plugins: [ extractCSS, extractLESS ] };
三:改造项目-抽离css
安装插件到项目
npm install extract-text-webpack-plugin --save-dev
配置webpack.config.js,加入ExtractTextPlugin和相关处理:
var webpack = require("webpack"); var path = require("path"); var srcDir = path.resolve(process.cwd(), 'src'); var nodeModPath = path.resolve(__dirname, './node_modules'); var pathMap = require('./src/pathmap.json'); var glob = require('glob') var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin; var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var entries = function () { var jsDir = path.resolve(srcDir, 'js') var entryFiles = glob.sync(jsDir + '/*.{js,jsx}') var map = {}; for (var i = 0; i < entryFiles.length; i++) { var filePath = entryFiles[i]; var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.')); map[filename] = filePath; } return map; } var html_plugins = function () { var entryHtml = glob.sync(srcDir + '/*.html') var r = [] var entriesFiles = entries() for (var i = 0; i < entryHtml.length; i++) { var filePath = entryHtml[i]; var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.')); var conf = { template: 'html!' + filePath, filename: filename + '.html' } //如果和入口js文件同名 if (filename in entriesFiles) { conf.inject = 'body' conf.chunks = ['vendor', filename] } //跨页面引用,如pageA,pageB 共同引用了common-a-b.js,那么可以在这单独处理 //if(pageA|pageB.test(filename)) conf.chunks.splice(1,0,'common-a-b') r.push(new HtmlWebpackPlugin(conf)) } return r } var plugins = []; var extractCSS = new ExtractTextPlugin('css/[name].css?[contenthash]') var cssLoader = extractCSS.extract(['css']) var sassLoader = extractCSS.extract(['css', 'sass']) plugins.push(extractCSS); plugins.push(new CommonsChunkPlugin({ name: 'vendor', minChunks: Infinity })); module.exports = { entry: Object.assign(entries(), { // 用到什么公共lib(例如jquery.js),就把它加进vendor去,目的是将公用库单独提取打包 'vendor': ['jquery', 'avalon'] }), output: { path: path.join(__dirname, "dist"), filename: "[name].js", chunkFilename: '[chunkhash:8].chunk.js', publicPath: "https://www.jb51.net/" }, module: { loaders: [ { test: /\.((woff2?|svg)(\?v=[0-9]\.[0-9]\.[0-9]))|(woff2?|svg|jpe?g|png|gif|ico)$/, loaders: [ //小于10KB的图片会自动转成dataUrl, 'url?limit=10000&name=img/[hash:8].[name].[ext]', 'image?{bypassOnDebug:true, progressive:true,optimizationLevel:3,pngquant:{quality:"65-80",speed:4}}' ] }, { test: /\.((ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9]))|(ttf|eot)$/, loader: 'url?limit=10000&name=fonts/[hash:8].[name].[ext]' }, {test: /\.(tpl|ejs)$/, loader: 'ejs'}, {test: /\.css$/, loader: cssLoader}, {test: /\.scss$/, loader: sassLoader} ] }, resolve: { extensions: ['', '.js', '.css', '.scss', '.tpl', '.png', '.jpg'], root: [srcDir, nodeModPath], alias: pathMap, publicPath: 'https://www.jb51.net/' }, plugins: plugins.concat(html_plugins()) }
其中,用ExtractTextPlugin 来抽离css
var ExtractTextPlugin = require('extract-text-webpack-plugin'); var extractCSS = new ExtractTextPlugin('css/[name].css?[contenthash]') var cssLoader = extractCSS.extract(['css']) var sassLoader = extractCSS.extract(['css', 'sass']) plugins.push(extractCSS); ...... //conf - module - loaders {test: /\.css$/, loader: cssLoader}, {test: /\.scss$/, loader: sassLoader}
注意事项:
css中img的路径会出现问题,通过设置publicPath 解决,采用绝对路径
output: { ...... publicPath: "https://www.jb51.net/" },
运行:
$ webpack
期望
css单独抽离,打包成单独的css文件
html自动引用css文件
小于10k的图片,转成base64 格式的 dataUrl
webpack.png 会被压缩,减少文件大小
运行webpack后的项目的目录结构:
生成的 dist/index.html 自动引用了 index.css 和相关的js,由于设置了publicPath 所以相应的链接都采用了绝对路径
生成的 dist/index.css 小图片被转成了data:image形式:
结果:
css单独打包到css目录
html自动注入了link 标签
small-webpack.png 小于10k,被打包进了index.css
webpack.png 由原来的50+k 被压缩成 10- k
最后,运行 webpack-dev-server 看一下运行结果:
总结