webpack v2 から webpack v4 にアップグレードしました。抽出テキスト プラグインが存在しないため、MiniCssExtract プラグインに置き換え、ファイル名を関数として処理できるようにアップグレードを延期する必要がありました。
これが利用可能になったので、webpack を実行していますが、アプリでは CSS 指向のものは何も実行されず、常に Uncaught SyntaxError: Unexpected token が取得されます。コンソールで。
最も単純な CSS でさえ試してみましたが、どの CSS ファイルもアプリで適切に実行されません。
シンプルな css-loader などに戻そうとしましたが、正常に動作するので、mini-css-extract-plugin の構成方法または見逃した愚かなことに関係があると考えています。
テーマ構成用のファイルが 1 つあります。
const fs = require('fs');
const merge = require('webpack-merge');
const path = require('path');
const lessPlugins = require('../Theme/plugins/customLess');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const themes = ['green', 'yellow'];
const getThemeConfig = (isDevBuild, themeNameToPassInToLess) => {
return {
test: /\.(css|less)$/,
use: ['style-loader',
{
loader: MiniCssExtractPlugin.loader,
options: {
importLoaders: 1,
hmr: isDevBuild
}
},
'css-loader',
'postcss-loader',
{
loader: "less-loader",
options: {
minimize: false,
plugins: [
lessPlugins
],
globalVars: {
themeName: themeNameToPassInToLess
}
}
}]
};
};
module.exports = {
getThemeConfig,
getCurrentTheme: () => {
const AppSettings = JSON.parse(stripJsonComments(fs.readFileSync('./appsettings.json').toString()));
if (AppSettings && AppSettings.ThemeConfig && AppSettings.ThemeConfig.ThemeName) {
return AppSettings.ThemeConfig.ThemeName;
}
return 'default';
},
getThemeConfigs: (isDevBuild, sharedConfig, bundleOutputDir) => {
const result = [];
for (const theme of themes) {
result.push(merge({
entry: {
[theme]: './Theme/sites/default.less'
},
output: {
path: path.join(__dirname, bundleOutputDir),
filename: '[name].[chunkhash].css',
publicPath: '/dist/'
},
module: {
rules: [getThemeConfig(isDevBuild, theme)]
}
}, sharedConfig));
}
return result;
}
};
メインの webpack ファイルは次のとおりです。
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const webpack = require('webpack');
const merge = require('webpack-merge');
const AutoPrefixer = require('autoprefixer');
const StatsWriterPlugin = require("webpack-stats-plugin").StatsWriterPlugin;
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const ForkTsCheckerNotifierWebpackPlugin = require('fork-ts-checker-notifier-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const WebpackMd5Hash = require("webpack-md5-hash");
const bundleOutputDir = './wwwroot/dist';
const themeHelpers = require('./Webpack/themes');
let stats = {};
const cpus = require('os').cpus().length;
const settings = fs.existsSync('./webpackSettings.json') ?
require('./webpackSettings.json') : {
typeCheckerWorkers: Math.min(2, cpus),
transpilerWorkers: Math.max(1, cpus - 3),
typeCheckingOverlay: true,
};
module.exports = (env, argv) => {
console.log(env);
const isDevBuild = !(env && env.prod);
const sharedConfig = {
devtool: isDevBuild ? 'source-map' : false,
mode: isDevBuild ? 'development' : 'production',
optimization: { minimize: !isDevBuild },
stats: {
modules: false
},
resolve: {
extensions: ['.js', '.jsx', 'json', '.ts', '.tsx', '.modern'],
modules: ['.', './', 'node_modules'],
alias: {
'../../theme.config$': path.join(__dirname, 'Theme/theme.config')
}
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.(png|jpg|jpeg|gif)$/,
use: 'url-loader?limit=25000'
},
{
test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
loader: 'file-loader?name=public/fonts/[name].[ext]'
}
]
},
plugins: [new MiniCssExtractPlugin({
disable: isDevBuild,
filename: (chunkData) => {
const name = chunkData.chunk.name.replace('js/build/', '').replace('components', 'base');
if (name.includes('admin') || name.includes('client') || name.includes('login')) {
return name + '-app.css';
}
return name + '.css';
},
chunkFilename: '[name].css'
}),
new ForkTsCheckerWebpackPlugin({
workers: settings.typeCheckerWorkers,
async: !settings.typeCheckingOverlay
}),
new webpack.LoaderOptionsPlugin({
minimize: !isDevBuild,
options: {
postcss: [AutoPrefixer]
}
}),
new WebpackMd5Hash()
]
.concat(settings.typeCheckingOverlay ? [] : [new ForkTsCheckerNotifierWebpackPlugin()])
.concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("development")
}
})
] : [
// Plugins that apply in production builds only
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
})
])
};
const clientConfig = merge({
entry: {
'main-client': './ClientApp/boot.tsx',
'login': './LoginApp/boot.tsx',
'admin': './AdminApp/boot.tsx'
},
module: {
rules: [{
test: /\.tsx?$/,
exclude: /node_modules/,
include: /ClientApp|LoginApp|AdminApp|CommonApp/,
use: [
`ifdef-loader?isDevBuild=${isDevBuild}`,
{
loader: 'awesome-typescript-loader',
options: {
silent: true,
transpileOnly: true,
useCache: true
}
}]
},
themeHelpers.getThemeConfig(isDevBuild, themeHelpers.getCurrentTheme())
]
},
output: {
path: path.join(__dirname, bundleOutputDir),
filename: isDevBuild ? '[name].js' : '[name].[chunkhash].js',
publicPath: '/dist/'
},
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
}),
new webpack.LoaderOptionsPlugin({
minimize: !isDevBuild,
options: {
postcss: [AutoPrefixer]
}
}),
new StatsWriterPlugin({
filename: '../../webpackstats.json',
transform(data) {
stats.assetsByChunkName = Object.assign({}, stats.assetsByChunkName, data.assetsByChunkName);
return JSON.stringify(stats, null, 4);
}
}),// Used by ScriptTagHelper
new WebpackMd5Hash()
]
}, sharedConfig);
if (isDevBuild) {
return clientConfig;
}
const themeConfigs = themeHelpers.getThemeConfigs(isDevBuild, sharedConfig, '.' + bundleOutputDir);
console.log('ThemeConfigs Rules', themeConfigs[0].module.rules[0]);
return [...themeConfigs, clientConfig];
};