因项目需要,用webpack搭建一个常用功能的环境。
初步功能罗列如下:
自动配置多入口出口
less转css
css前缀自动补齐
css提取成单独文件
css压缩
图片压缩
引入字体和svg js Babel 压缩
css和js的分离/合并和过滤
1.建立并且进入文件夹
mkdir webpack4.29.6 && cd webpack4.29.6
复制代码
2.如下图建立各个demo文件和图片
index.html:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>test</title>
</head>
<body>随便写一些index2333
</body>
</html>
复制代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>test</title>
</head>
<body>随便写一些about2333
</body>
</html>
复制代码
其他的文件可以先空着,图片先不导入也没关系。
3建立package.json(以下所有命令都是在webpack4.29.6文件夹下运行)
npm init -y
复制代码
4.安装以下几个依赖
(webpack/webpack-cli这两个需要注意,3.x以前版本是合并在一起的,4.x后拆分了
webpack-dev-server:起服务
html-webpack-plugin:动态生成html
webpack-merge:合并webpack配置文件)
npm install -D webpack webpack-cli webpack-dev-server html-webpack-plugin webpack-merge
复制代码
确保局部依赖和全局依赖版本都如下图是最新的(看清楚了,webpack是4.29.6的,如果你因为网络问题装成3.几的,后面将全部报错。这步很关键,不然你会有无穷尽的麻烦,如果实在不成功可以先把全局node下的webpack相关文件删除,window在c盘/Program Files/nodejs/下)。
5.建立三个webpack配置文本(1.common2.dev3.prod)并且分别写入
touch webpack.common.js webpack.dev.js webpack.prod.js
复制代码
webpack.common.js:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");module.exports = {entry: {index: "./src/js/index.js"},output: {//[name] 输出名称等于输入名称 [contenthash:8] 八位hashfilename: "[name].[contenthash:8].js", //你应该知道的node path 知识: http://nodejs.cn/api/path.htmlpath: path.resolve(__dirname, "dist")},module: {rules: []},plugins: [new HtmlWebpackPlugin({filename: "index.html",template: "./src/index.html"})]
};复制代码
webpack.dev.js:
const merge = require("webpack-merge");
const common = require("./webpack.common.js");module.exports = merge(common, {mode: "development",//开启调试devtool: "source-map",devServer: {//设置基本目录结构contentBase: "./dist",//服务器的IP地址,可以使用IP也可以使用localhosthost: "localhost",//服务端压缩是否开启compress: true,//配置服务端口号port: 8090}
});复制代码
webpack.prod.js:
const merge = require("webpack-merge");
const common = require("./webpack.common.js");module.exports = merge(common, {mode: "production",
});复制代码
6.修改下package.json中的script对象
"scripts": {"dev": "webpack-dev-server --config webpack.dev.js","build": "rimraf dist && webpack --config webpack.prod.js"},
复制代码
7.尝试启动服务或者打包
启动服务:
npm run dev
复制代码
打包: (rimraf dist: 打包前删除了rimraf文件夹再重新生成)
npm run build
复制代码
dist:
因为修改了配置文件每步都要重启服务比较麻烦,我们这里引入nodemon。并且添加一条命令
npm install -D nodemon
复制代码
// 监听webpack.common.js文件,有变动的话就重新启动 npm run dev
"startdev": "nodemon --watch webpack.common.js --exec npm run dev "
复制代码
package.json:
开始正式配置项目常见的功能
前面打包的文件图片可以看到只打出了index.html,这里看看怎么引入多个html
webpack.common.js: 在入口增加多一个about.js和插件多生产一个实例即可:
在根目录新建一个multi.page.js文件:
multi.page.js:
// 多入口出口处理
const path = require("path");
const fs = require("fs");
const htmlWebpackPlugin = require("html-webpack-plugin");
const pagesPath = path.resolve("./src");var pageList = [];
function readPages() {fs.readdirSync(pagesPath).forEach(e => {var fullPath = pagesPath + "/" + e;if (e.includes("html")) {var baseName = e.slice(0, e.indexOf("."));pageList.push({entry: pagesPath + "\\js\\" + baseName + ".js",chunkName: baseName,template: pagesPath +'\\'+ e});}});return pageList;
}// 入口
exports.getEntryPages = function() {return readPages().reduce((r, page) => {r[page.chunkName] = page.entry;return r;}, {});
};
//出口
exports.htmlPlugins = function() {var list = readPages().map(page => {var options = {filename: page.chunkName + ".html",template: page.template,chunks: [page.chunkName]};return new htmlWebpackPlugin(options);});return list;
};复制代码
webpack.common.js:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const multiPage = require("./multi.page");module.exports = {// entry: {// index: "./src/js/index.js",// about: "./src/js/about.js"// },entry: multiPage.getEntryPages(),output: {//[name] 输出名称等于输入名称 [contenthash:8] 八位hashfilename: "[name].[contenthash:8].js",//你应该知道的node path 知识: http://nodejs.cn/api/path.htmlpath: path.resolve(__dirname, "dist")},module: {rules: []},plugins: [// new HtmlWebpackPlugin({// filename: "index.html",// template: "./src/index.html"// }),// new HtmlWebpackPlugin({// filename: "about.html",// template: "./src/about.html"// })...multiPage.htmlPlugins()]
};复制代码
就是将手动引入导出改善成nodejs自动遍历
后面就是常见功能了,先暂时写到webpack.common.js里面方便调试,最后按需切到webpack.dev.js或者webpack.prod.js
处理css(这里我以less为例)安装以下依赖
npm install -D css-loader style-loader less less-loader
复制代码
修改webpack.common.js:
module: {rules: [{test: /\.less$/,use: ["style-loader", "css-loader", "less-loader"],include: path.resolve(__dirname, "./src") // 制定路径提升性能}]},
复制代码
修改index.js引入index.less,并且随意写点样式
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>test</title>
</head>
<body><div class="test">随便写点什么 这里不要自己引入css和js 全部交给webpack来处理</div>
</body>
</html>
复制代码
index.js:
import index from "../css/index.less";
复制代码
index.less
body {display: flex;background: #666;.test {color: #ff0;}
}
复制代码
就会发现相关样式在head style 里了
再优化一步,将style提出来
安装依赖mini-css-extract-plugin
npm install -D mini-css-extract-plugin
复制代码
webpack.common.js 引进依赖、修改规则和产出,文件总体如下
webpack.common.js:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const multiPage = require("./multi.page");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //提取css文件module.exports = {// entry: {// index: "./src/js/index.js",// about: "./src/js/about.js"// },entry: multiPage.getEntryPages(),output: {//[name] 输出名称等于输入名称 [contenthash:8] 八位hashfilename: "[name].[contenthash:8].js",//你应该知道的node path 知识: http://nodejs.cn/api/path.htmlpath: path.resolve(__dirname, "dist")},module: {rules: [{test: /\.less$/,// use: ["style-loader", "css-loader", "less-loader"],use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],include: path.resolve(__dirname, "./src") // 制定路径提升性能}]},plugins: [// new HtmlWebpackPlugin({// filename: "index.html",// template: "./src/index.html"// }),// new HtmlWebpackPlugin({// filename: "about.html",// template: "./src/about.html"// })...multiPage.htmlPlugins(),new MiniCssExtractPlugin({filename: "css/[name].[contenthash:8].css"})]
};复制代码
继续优化将css前缀自动补齐
安装依赖:
npm install -D postcss-loader autoprefixer
复制代码
修改package.json:
"browserslist": ["> 1%","last 2 versions","not ie <= 8"]
复制代码
修改webpack.common.js:
--- use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
+++ use: [MiniCssExtractPlugin.loader,"css-loader",{loader: "postcss-loader",options: {plugins: () => [require("autoprefixer")()]}},"less-loader"],
复制代码
最后压缩css文件
安装依赖:
npm install -D optimize-css-assets-webpack-plugin
复制代码
修改webpack.common.js:
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')new OptimizeCssAssetsPlugin({assetNameRegExp: /\.css$/g, cssProcessor: require('cssnano'), //用于优化\最小化CSS的CSS处理器,默认为cssnanocssProcessorOptions: { safe: true, discardComments: { removeAll: true } }, //传递给cssProcessor的选项,默认为{}canPrint: true //一个布尔值,指示插件是否可以将消息打印到控制台,默认为true
}),
复制代码
查看一下结果 源文件:
引入图片以及对图片进行压缩
npm install -D css-loader file-loader html-withimg-loader image-webpack-loader
复制代码
webpack.common.js:
{test: /\.(svg|png|jpe?g|gif)$/i,use: [{loader: "url-loader",options: {limit: 1,name: "images/[name].[contenthash:8].[ext]",publicPath: "../"}},{loader: "image-webpack-loader",options: {pngquant: {quality: "70-80",speed: 1}}}]},{test: /\.html$/,use:['html-withimg-loader']}
复制代码
引入字体
修改webpack.common.js:
{test: /\.(woff|woff2|eot|ttf|otf)$/,use: [{loader: "file-loader",options: {name: "assets/[name].[contenthash:8].[ext]",publicPath: "../"}}]}复制代码
babel 升级后有点小恶心..不想说了 后面再根据项目丰富css和js的提取和合并过滤
from:webpack.docschina.org/api/