I guess I'll start with my webpack config.
const webpack = require('webpack');
const path = require('path');
/**
* Environment
*/
const nodeEnv = process.env.NODE_ENV || 'development';
const isProduction = nodeEnv === 'production';
const isDevelopment = !isProduction;
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const sourcePath = path.join(__dirname, 'assets');
const buildPath = path.join(__dirname, 'dist');
const extractSass = new ExtractTextPlugin({
filename: '[name].[contenthash].css',
disable: isDevelopment
});
/**
* Plugins
*/
const plugins = [
new HtmlWebpackPlugin({
template: path.join(sourcePath, 'index.html'),
}),
extractSass
];
if (isProduction) {
} else {
plugins.concat([
new webpack.HotModuleReplacementPlugin(),
]);
}
module.exports = {
entry: ['./assets/app.js', './assets/app.scss'],
devtool: isProduction ? 'eval' : 'source-map',
plugins: plugins,
module: {
rules: [{
test: /\.scss$/,
use: extractSass.extract({
use: [{
loader: "css-loader"
}, {
loader: "sass-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}]
},
output: {
filename: 'bundle.js',
path: buildPath
},
devServer: {
contentBase: buildPath,
port: 9000
}
};
This all works fine when running on the webpack dev server but I'm trying to figure out how this fits together on a production environment.
As you can see, as per the sass-loader documentation, I'm creating a file called [name].[contenthash].css
if NODE_ENV
is set to production
. I love the idea of serving files based on the content hash because I love integrity.
The difficulty I'm having is understanding how I can pass that file name, that content hash into the index.html template I'm creating so that I can <link>
the stylesheet.
I just don't understand how these two components come together to produce a publishable build. HtmlWebpackPlugin
produced a .html in the output directory but obviously it has no innate understanding of where to find it's styles.
Your config seems correct.
Is there any way to pass that file name into the HTML template on production?
What should be happening is that the HtmlWebpackPlugin
should be creating a new index.html
file in your buildPath
directory, which has the generated bundles automatically injected in it (for example the generated CSS bundle will be injected in the head
tag and the generated script bundles at the bottom of the body
tag)
Beyond that it is just a matter of serving that dist/index.html
to whoever visits your site/app. So the answer to
Is it a server side thing?
is yes.
Try doing a build without the dev server, by simply running webpack
, so you can see the output of your configuration (the dev server builds things in memory, so you do not actually get to see them)