文章目录
项目地址:
https://github.com/withwz/webpack-mulitpage-demo
webpack打包多页demo
配置了scss
使用scss来写css提高效率
配置了postcss
自动补全css浏览器前缀和rem自动转换
无需再写css3各浏览器的前缀,也无需用rem这种难以心算的单位来布局了,设计稿多少就敲多少px。
内置了jquery
直接可以使用“&”无需引入script文件或者用require import来引入。
可以放心的写多页应用
可以像图片中目录一样嵌套,
建议每一个文件中只包含一个*.html,一个*.scss,一个*.ts,这样结构是最清晰的表现形式,可以在一个文件中嵌套另一个文件保存同样的内容,程序会递归所有的文件夹。
❗ 不建议一个文件中包含多个*.html.
源代码
目录结构
package.json
{
"name": "wptest",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --config webpack.config.js",
"build": "cross-env NODE_ENV=production webpack --config webpack.config.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/jquery": "^3.3.31",
"autoprefixer": "^9.6.1",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.2.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"html-webpack-plugin": "^3.2.0",
"jquery": "^3.4.1",
"lodash": "^4.17.15",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"postcss-nested": "^4.1.2",
"postcss-px2rem": "^0.3.0",
"sass-loader": "^7.2.0",
"style-loader": "^1.0.0",
"ts-loader": "^6.0.4",
"typescript": "^3.5.3",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^4.39.2",
"webpack-cli": "^3.3.7",
"webpack-dev-server": "^3.8.0",
"webpack-merge": "^4.2.1"
}
}
webpack.config.js
const rimraf = require('rimraf')
const webpackConfig = process.env.NODE_ENV === 'development'
? require('./build/webpack.dev.js')
: require('./build/webpack.prod.js')
if (process.env.NODE_ENV !== 'development') {
rimraf('./dist', function (err) {
if (err) throw err
})
}
module.exports = webpackConfig
webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const webpack = require('webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const config = require('./entries');
console.log('============================', config.entries, '=============================')
const entries = {};
config.entries.forEach(function (entry) {
entries[entry.entryName] = entry.entry;
});
console.log('............................', entries, '.................................')
const webpackConfig = {
entry: entries,
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
'css-loader',
'postcss-loader',
'sass-loader',
],
})
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',
}),
new CleanWebpackPlugin(),
/* https://doc.webpack-china.org/plugins/extract-text-webpack-plugin/ 它会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。 因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。 */
new ExtractTextPlugin({
filename: 'asset/css/[name].[sha1:contenthash:hex:7].css',
allChunks: true
}),
],
output: {
filename: 'asset/js/[name].bundle.js',
path: path.resolve(__dirname, '../dist'),
publicPath: '/'
}
};
config.entries.forEach(function (entry) {
const options = {
filename: entry.filename,
template: entry.template,
chunks: ['manifest', 'vendor', 'app', entry.entryName],
}
// https://github.com/jantimon/html-webpack-plugin
webpackConfig.plugins.push(new HtmlWebpackPlugin(options))
});
module.exports = webpackConfig
entries.js
let path = require('path');
let fs = require('fs');
let dirSrc = path.resolve(__dirname, '../src')
let entriesConfig = [
{
entryName: 'index/index',
entry: path.resolve(dirSrc, 'index.ts'),
filename: 'index.html',
template: path.resolve(dirSrc, '../index.html')
}
];
//获取src下的所有目录
let dirPages = fs.readdirSync(dirSrc).filter(function (dirName) {
return fs.statSync(dirSrc + '/' + dirName).isDirectory()
})
dirPages.forEach(pageWalk)
function pageWalk(pageName) {
let filemark = 'index'
let pagePath = path.resolve(dirSrc, pageName)
let files = fs.readdirSync(pagePath)
let fileHTML = filemark + '.html'
let fileTS = filemark + '.ts'
//获取有*.ts和*.html的文件
if (files.indexOf(fileHTML) === -1 || files.indexOf(fileTS) === -1) return
let filename = pageName + '/' + fileHTML
console.log('==========', path.resolve(dirSrc, pageName, fileTS), '=================')
entriesConfig.push({
entryName: pageName + '/' + filemark,
entry: path.resolve(dirSrc, pageName, fileTS),
filename: filename,
template: path.resolve(dirSrc, filename)
})
let subDirs = files.filter(function (file) {
return fs.statSync(pagePath + '/' + file).isDirectory()
}).map(function (dirName) {
return pageName + '/' + dirName
})
if (subDirs.length) {
subDirs.forEach(pageWalk)
}
}
module.exports = {
entries: entriesConfig,
}
webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
}
});
webpack.prod.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
}
});
postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')({
browsers: ['last 100 versions'] //必须设置支持的浏览器才会自动添加添加浏览器兼容
}),
require('postcss-px2rem')
]
}