我已经从 webpack v2 升级到 webpack v4 - 因为提取文本插件不再存在我已经用 MiniCssExtract 插件替换它并且不得不推迟升级,以便我可以将文件名作为函数处理。
既然这是可用的,我正在运行 webpack,但是在我的应用程序中没有任何面向 css 的内容将运行我将始终得到: Uncaught SyntaxError: Unexpected token 。在控制台中。
我什至尝试过最简单的 CSS,但没有任何 CSS 文件可以在应用程序中正确执行。
我试图剥离回简单的 css-loader 等,它们工作正常,所以我认为这与配置 mini-css-extract-plugin 的方式或我错过的一些愚蠢的事情有关。
我的主题配置有一个文件:
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];
};