Please find my webpack config below:
const LinkTypePlugin = require('html-webpack-link-type-plugin').HtmlWebpackLinkTypePlugin;
const path = require('path');
const webpack = require('webpack');
const FileManagerPlugin = require('filemanager-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = function(env) {
const config = {};
config.entry = {
'apps/xyz': './apps/xyz/index.js',
};
config.mode = (env && env.NODE_ENV) || 'production';
config.output = {
path: path.resolve(__dirname, './dist'),
filename: './[name]/bundle.[hash].js',
};
if (config.mode === 'development') {
config.devtool = 'eval-source-map';
} else {
config.devtool = false;
}
config.module = {
rules: [
{
test: /\.jsx?$/,
exclude: /[\\/]node_modules[\\/]\.+/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: 'defaults',
useBuiltIns: 'entry',
corejs: 3,
},
],
'@babel/preset-react',
],
plugins: [
'@babel/plugin-proposal-class-properties',
...(config.mode === 'production'
? [['transform-react-remove-prop-types', { removeImport: true }]]
: []),
],
},
},
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
// loader for processing sass templates used by react files
{
test: /\.(sass|scss|css)$/,
exclude: /[\\/]node_modules[\\/]\.+/,
use: [
config.mode === 'production'
? {
loader: MiniCssExtractPlugin.loader,
options: { publicPath: '../' },
}
: 'style-loader',
'css-loader',
'sass-loader',
],
},
{
test: /\.(jpe?g|png|gif|svg|bmp)$/i,
loader: 'file-loader',
options: {
name: './[path][hash].[ext]',
useRelativePaths: true,
},
},
],
};
config.resolve = {
extensions: ['.tsx', '.ts', '.js'],
alias: {
src: path.resolve(__dirname),
},
};
// Configure plugins
config.plugins = [
new CleanWebpackPlugin(),
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en-gb/),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './apps/xyz/index.html'),
filename: 'apps/xyz/index.html',
chunks: ['apps/xyz'],
minify: {
removeStyleLinkTypeAttributes: false,
removeScriptTypeAttributes: false,
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
useShortDoctype: true,
},
}),
new MiniCssExtractPlugin({
filename: './[name]/main.[hash].css',
chunkFilename: './[name]/main-[id].[hash].css',
insert: 'text/css',
linkType: 'text/css',
}),
new LinkTypePlugin({
'**/*.css': 'text/css',
}),
new FileManagerPlugin({
onEnd: [
{
delete: ['../extension/public'],
copy: [
{
source: './dist/',
destination: '../extension/public/',
},
],
},
],
}),
];
// Adding new version of uglifyjs plugin as required by other packages
if (env && env.NODE_ENV === 'production') {
config.plugins.push(new UglifyJSPlugin());
}
return config;
};
The index.html file generated has the CSS attached but without type=text/css which I need for strict type compatibility. Please help.
The issue was the glob I specified in LinkTypePlugin
**/*.cssis not an all-cover scenario. I changed it to./**/*.cssand it works!The key is to look at the generated
index.html. The injectedlinks'shreforsrcwill help in defining your glob pattern.In cases where the generated files' path is not very straightforward,
MiniCssExtractPluginisn't able to do much.