此刻,我有了Webpack 4和Handlebars结构
src/
├── assets/
│ ├── css/
│ ├── fonts/
│ ├── img/
│ ├── js/
│ ├── scss/
│ └── vendor/
├── helpers/
│ ├── repeat.js
│ └── compare.js
├── partials/
│ ├── header.hbs
│ └── footer.hbs
├── index.hbs
├── subpage1.hbs
└── subpage2.hbs
它很好地融合了
dest/
├── assets/
│ ├── css/
│ ├── fonts/
│ ├── img/
│ ├── js/
│ ├── scss/
│ └── vendor/
├── index.html
├── subpage1.html
└── subpage2.html
我可以接受,但客户端希望包含另一个index.html而不是subpage1.html
,subpage2.html
...子文件夹/subpage1/
等,以便他们可以使用漂亮的网址没有任何htaccess,并且正如他们所说的那样:-/
问题是如何复制子目录并处理其中的把手文件:
src/
├── assets/
│ ├── css/
│ ├── fonts/
│ ├── img/
│ ├── js/
│ ├── scss/
│ └── vendor/
├── helpers/
│ ├── repeat.js
│ └── compare.js
├── partials/
│ ├── header.hbs
│ └── footer.hbs
├── subpage1/
│ └── index.hbs
├── subpage2/
│ └── index.hbs
└── index.hbs
如果我成功完成此步骤,将面临另一个挑战-处理相对路径并使它们成为图像,css,bundle.js的绝对路径
这是我的webpack通用配置:
const path = require('path');
const webpack = require('webpack');
const handlebars = require('handlebars');
const utils = require('handlebars-utils');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const vars = require('./variables.js');
const glob = require('glob');
const generateHTMLPlugins = () =>
glob.sync('./src/*.{html,hbs}').map(item => {
return new HtmlWebpackPlugin({
filename: path.parse(item).name + '.html',
template: item
});
});
module.exports = {
context: vars.relativePath,
entry: [
vars.src.relativePath + vars.src.assetsPath + 'js/scripts.js'
],
output: {
path: vars.dist.relativePath,
filename: vars.dist.assetsPath + 'js/bundle.js'
},
plugins: [
new webpack.LoaderOptionsPlugin({
options: {
handlebarsLoader: {}
}
}),
new CopyWebpackPlugin([ // images folder
{
from: vars.src.relativePath + vars.src.assetsPath + 'img',
to: vars.dist.relativePath + vars.dist.assetsPath + 'img'
}
]),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
}),
...generateHTMLPlugins()
],
module: {
rules: [
{
test: /\.js?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.hbs$/,
loader: 'handlebars-loader',
query: {
helperDirs: [vars.src.relativePath + 'helpers'],
partialDirs: [vars.src.relativePath + 'partials'],
precompileOptions: {
knownHelpersOnly: false,
},
}
},
{ // Compile and merge sass + css
test: /\.s?css/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
sourceMap: (this.mode == 'production') ? false : true
}
},
{
loader: 'css-loader',
options: {
sourceMap: (this.mode == 'production') ? false : true
}
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer'),
require('cssnano')({
discardComments: { removeAll: true }
}),
],
sourceMap: (this.mode == 'production') ? false : true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: (this.mode == 'production') ? false : true
}
}
]
},
{ // Fonts
test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
exclude: /img\//,
use: {
loader: "file-loader",
options: {
name: '[name].[ext]',
publicPath: '../fonts/',
outputPath: vars.dist.assetsPath + 'fonts/',
}
},
},
{ // Context images
test: /\.(jpe?g|png|gif|svg)/,
exclude: /font/,
use: {
loader: "file-loader",
options: {
name: '[name].[ext]',
publicPath: '../img/',
outputPath: vars.dist.assetsPath + 'img/'
}
}
},
]
}
};
Webpack变量:
const path = require('path');
const relativePath = path.resolve(__dirname, '../');
const argv = require('yargs').argv;
const theme = (argv.name === undefined) ? 'default' : argv.name
module.exports = {
relativePath: relativePath,
dist: {
path: 'dist/',
relativePath: relativePath + '/dist/',
assetsPath: 'assets/'
// assetsPath: 'assets/' + theme + '/'
},
src: {
path: 'src/',
relativePath: relativePath + '/src/',
assetsPath: 'assets/'
// assetsPath: 'assets/' + theme + '/'
}
}
和生产配置
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const AggressiveMergingPlugin = require('webpack/lib/optimize/AggressiveMergingPlugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const vars = require('./variables.js');
module.exports = merge(common, {
output: {
path: vars.dist.relativePath,
filename: vars.dist.assetsPath + 'js/bundle.js'
},
mode: 'production',
plugins: [
new MiniCssExtractPlugin({
filename: vars.dist.assetsPath + 'css/style.min.css',
allChunks: true,
}),
new UglifyJsPlugin(), //minify everything
new AggressiveMergingPlugin(), //Merge chunks
new CleanWebpackPlugin([vars.dist.path],{
root: vars.relativePath
})
]
})
答案 0 :(得分:0)
所以..我找到了一种解决方案..也许不是一个优雅的解决方案,但是它可行。这是用于递归hbs到html的,除了partials dir:
glob.sync('./src/**/*.{html,hbs}', {"ignore": ['./src/partials/*']} ).map(item => {
return new HtmlWebpackPlugin({
// filename: path.parse(item).name + '.html',
filename: path.resolve(__dirname, '../') + path.parse(item).dir.replace('./src', '/dist') + '/' + path.parse(item).name + '.html',
template: item
});
});
并最终为公众设置绝对路径
output: {
path: vars.dist.relativePath,
publicPath: '/',
filename: vars.dist.assetsPath + 'js/bundle.js'
},