Webpack 多页面打包
功能
- 打包编译JS
- 压缩合并css
- 图片打包处理
- rem手机适配
- postcss
- 多页面导航生成
- 模块热替换
开发环境
npm run start
打包环境
npm run build
项目地址
github: https://github.com/SupaFan/webpack-dev
知识点
- webpack js 编译 css压缩合并 html压缩 模块热替换
- nodejs 增删目录 增加文件
- postcss
- fetch
- es6
package.json
{
"name": "sps-webpack",
"version": "1.0.0",
"description": "webpack打包多页面解决方案",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --progress --env.NODE_ENV=build",
"dev": "webpack --watch --progress --color -d --env.NODE_ENV=dev",
"start": "webpack-dev-server --watch --open --env.NODE_ENV=dev"
},
"keywords": [],
"author": "https://github.com/SupaFan",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^7.1.4",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-latest": "^6.24.1",
"clean-webpack-plugin": "^0.1.17",
"cross-env": "^5.1.1",
"css-loader": "^0.28.7",
"cssnano": "^3.10.0",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.30.1",
"image-webpack-loader": "^3.4.2",
"jquery": "^3.2.1",
"postcss-adaptive": "^0.4.0",
"postcss-cssnext": "^3.0.2",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.6",
"style-loader": "^0.18.2",
"sugarss": "^1.0.0",
"url-loader": "^0.5.9",
"webpack": "^3.5.6",
"webpack-dev-server": "^2.9.5",
"webpack-manifest-plugin": "^1.3.2",
"weixin-js-sdk": "^1.2.0"
},
"dependencies": {}
}
webpack.config.js
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
// 模块映射到输出 bundle 的过程
const ManifestPlugin = require('webpack-manifest-plugin');
// 打包地址
const buildPath = path.resolve(__dirname, './dist');
// 模板地址
const templateRoot = path.resolve(__dirname, './page');
// NODEJS FS 删除文件
let emptyDir = function (fileUrl) {
let files = fs.readdirSync(fileUrl); //读取该文件夹
files.forEach(function (file) {
let stats = fs.statSync(fileUrl + '/' + file);
if (stats.isDirectory()) {
emptyDir(fileUrl + '/' + file);
} else {
fs.unlinkSync(fileUrl + '/' + file);
console.log("删除文件 " + fileUrl + ' ````' + file + "```` 成功");
}
});
};
// 页面入口
const pageEntry = {};
// 页面模板
const pageHtml = [];
// 导航JSON
const navigation = {
"navList": []
};
// 检查是否有打包目录
!fs.existsSync(buildPath) && fs.mkdirSync(buildPath);
// 读取文件目录
const pages = fs.readdirSync(templateRoot)
pages.forEach((name, index) => {
// 页面入口配置
const enterPath = path.join(templateRoot, name)
pageEntry[name] = path.join(enterPath, 'entry.js')
// 输出页面模板
pageHtml.push(new HtmlWebpackPlugin({
entryName: name,
filename: `${name}.html`,
template: `${enterPath}/index.html`,
inject: false,
minify: {
removeComments: true,
collapseWhitespace: true
},
chunks: ['main', 'common', name]
}))
// 输出导航JSON
navigation.navList.push({
"name": name,
"href": `/${name}.html`
})
fs.writeFileSync(path.resolve(__dirname, './Navigation.json'), JSON.stringify(navigation));
})
module.exports = env => {
const config = {publicPath: '/'}
emptyDir(buildPath)
if (env.NODE_ENV === 'build') {
config.publicPath = './'
}
return {
entry: Object.assign(pageEntry, {
main: './public/main.js'
}),
// devtool: false,
devtool: 'source-map',
devServer: {
contentBase: path.resolve(__dirname, './'),
compress: true,
inline: true,
hot: true, // 模块热替换
port: 9000,
},
plugins: [
new ManifestPlugin(),
new webpack.HotModuleReplacementPlugin(), // 模块热替换
new webpack.optimize.CommonsChunkPlugin({ // 公共模块提取
name: 'common'
}),
// 清理 项目之外无法清理 用nodejs清理文件
// new CleanWebpackPlugin(buildPath),
].concat(pageHtml),
output: {
filename: 'js/[name]-[hash].bundle.js',
path: buildPath,
publicPath: config.publicPath
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
]
}, {
test: /\.(png|jpg|gif)$/,
use: [
'url-loader?limit=20000&name=[name]-[hash].[ext]&outputPath=images/',
'image-webpack-loader'
]
}, {
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader']
},
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['latest']
}
},
exclude: '/node_modules/',
include: '/src/',
}
]
}
}
}