Reputation: 2426
I'm building a SPA on Webpack to try to learn the ecosystem and philosophy behind it. To be clear - there's probably an easy, hacky way of quickly doing what I want; but I don't want to know about it - I want the 'correct', best-practices way.
I've managed to set up compilation for Typescript, Sass, etc; but the one thing I can't wrap my head around is HTML. Coming from Gulp.js, I previously had a gulpfile.js
that took src/index.html
and placed it directly into dist/
.
However, I'm seeing references that indicate that I shouldn't be writing my own index.html
, if possible:
https://www.npmjs.com/package/html-webpack-plugin: "You can either let the plugin generate an HTML file for you [...]"
https://github.com/jaketrent/html-webpack-template: "[This plugin] will hopefully make it less likely that you'll have to create your own
index.html
file in your webpack project."
I just don't understand how I could possibly not have a pre-defined HTML structure. Where do I make my navbar, my footer, the content of the page?
The fact that I'm having to ask this question at all instead of an obvious answer presenting itself indicates to me that I'm going about this the wrong way. If I use the Vue CLI to generate a web app, for example, I notice that index.html
isn't moved into dist/
at all and is instead exposed via public/index.html
.
What's the correct way to get my HTML structure into my built distribution?
Upvotes: 0
Views: 57
Reputation: 299
First of all, you should make the difference between classic SPA with Vue/React and static HTML with Vue/React. SPA are rendered on client side, that means there is more or less an empty HTML and everything will be rendered by JavaScript, so there's no reason to to write plain HTML.
But you can use an HTML Engine like Twig/Nunjucks with html-webpack-plugin
and template. You can learn that from https://darvin.dev
, its a HTML Webpack Boilerplate.
const prod = {
module: {
rules: [{
test: /\.njk$/,
use: [{
loader: 'simple-nunjucks-loader',
options: {
searchPaths: [
`${ROOT_PATH}/${global.inputDirs.src}/${global.inputDirs.templates}/`,
],
assetsPaths: [
`${ROOT_PATH}/${global.inputDirs.src}/${global.inputDirs.assets}/`,
],
filters: {
sizes: `${ROOT_PATH}/webpack/settings/html-njk/config/nunjucks.filters.size.js`,
},
globals: {
darvinEnv: `${ROOT_PATH}/webpack/settings/html-njk/config/nunjucks.global.js`,
}
}
}]
}]
},
plugins: [
// loop here for each html file
new HtmlWebpackPlugin({
filename: targetPath + `.html`,
template: `${global.inputDirs.src}/${global.inputDirs.templates}/${targetPath}.${global.template.extIn}`,
hash: true,
inject: `body`,
cache: true,
chunks: [elementObj.chunkName],
templateParameters: {
darvin: elementObj,
sprite: allIconsInDir
},
minify: {
collapseWhitespace: false,
conservativeCollapse: false,
removeComments: false,
removeRedundantAttributes: false,
removeScriptTypeAttributes: false,
removeStyleLinkTypeAttributes: false,
useShortDoctype: false,
removeAttributeQuotes: false,
removeEmptyAttributes: false,
removeEmptyElements: false,
removeOptionalTags: false
}
});
],
};
Upvotes: 1