Skip to content

Commit b1cbcd8

Browse files
committed
vue ssr MiniCssExtractPlugin error webpack-contrib/mini-css-extract-plugin#90
1 parent ef2fdce commit b1cbcd8

7 files changed

+190
-116
lines changed

build/webpack.base.conf.js

+110-109
Original file line numberDiff line numberDiff line change
@@ -5,121 +5,122 @@ const { VueLoaderPlugin } = require('vue-loader');
55
const ESLintPlugin = require('eslint-webpack-plugin');
66
const CopyWebpackPlugin = require('copy-webpack-plugin');
77

8-
module.exports = {
9-
performance: {
10-
// 资源文件最大限制大小warning提示 1000kb
11-
maxAssetSize: 1000 * 1024,
12-
maxEntrypointSize: 1000 * 1024,
13-
},
14-
output: {
15-
filename: '[name].[chunkhash].js',
16-
chunkFilename: '[name].[chunkhash].js',
17-
path: path.resolve(__dirname, '../dist'),
18-
publicPath: '',
19-
},
20-
module: {
21-
rules: [
22-
{
23-
test: /\.vue$/,
24-
loader: 'vue-loader'
25-
},
26-
{
27-
test: /\.m?js$/,
28-
loader: 'babel-loader',
29-
exclude: file => {
30-
return /node_modules/.test(file)
31-
}
32-
},
33-
{
34-
test: /\.s?css$/i,
35-
use: [
36-
{
37-
loader: MiniCssExtractPlugin.loader,
38-
options: {
39-
publicPath: '../'
40-
}
41-
},
42-
{
43-
loader: "css-loader",
44-
options: { importLoaders: 1 },
45-
},
46-
{
47-
loader: "postcss-loader",
48-
options: {
49-
postcssOptions: {
50-
plugins: [
51-
[
52-
"autoprefixer",
53-
{
54-
// Options
55-
},
8+
module.exports = platform => {
9+
return {
10+
performance: {
11+
// 资源文件最大限制大小warning提示 1000kb
12+
maxAssetSize: 1000 * 1024,
13+
maxEntrypointSize: 1000 * 1024,
14+
},
15+
output: {
16+
filename: '[name].[chunkhash].js',
17+
chunkFilename: '[name].[chunkhash].js',
18+
path: path.resolve(__dirname, '../dist'),
19+
publicPath: '',
20+
},
21+
module: {
22+
rules: [
23+
{
24+
test: /\.vue$/,
25+
loader: 'vue-loader',
26+
options: {
27+
extractCSS: true
28+
}
29+
},
30+
{
31+
test: /\.m?js$/,
32+
loader: 'babel-loader',
33+
exclude: file => {
34+
return /node_modules/.test(file)
35+
}
36+
},
37+
{
38+
test: /\.s?css$/i,
39+
use: [
40+
platform == 'server' ? {
41+
loader: 'null-loader'
42+
} : {
43+
loader: MiniCssExtractPlugin.loader,
44+
options: {
45+
publicPath: '../'
46+
}
47+
},
48+
{
49+
loader: "css-loader",
50+
options: { importLoaders: 1 },
51+
},
52+
{
53+
loader: "postcss-loader",
54+
options: {
55+
postcssOptions: {
56+
plugins: [
57+
[
58+
"autoprefixer",
59+
{
60+
// Options
61+
},
62+
],
5663
],
57-
],
64+
},
5865
},
5966
},
67+
'sass-loader'
68+
],
69+
},
70+
{
71+
test: /\.(png|svg|jpg|jpeg|gif|webp)$/i,
72+
// asset 自动地在 asset/resource 和 asset/inline 之间进行选择, 默认size < 8kb 实行asset/inline
73+
type: 'asset',
74+
parser: {
75+
dataUrlCondition: {
76+
maxSize: 4 * 1024 // 4kb
77+
}
78+
},
79+
generator: {
80+
filename: 'images/[name].[hash][ext]',
6081
},
61-
'sass-loader'
62-
],
63-
},
64-
{
65-
test: /\.(png|svg|jpg|jpeg|gif|webp)$/i,
66-
// asset 自动地在 asset/resource 和 asset/inline 之间进行选择, 默认size < 8kb 实行asset/inline
67-
type: 'asset',
68-
parser: {
69-
dataUrlCondition: {
70-
maxSize: 4 * 1024 // 4kb
71-
}
7282
},
73-
generator: {
74-
filename: 'images/[name].[hash][ext]',
83+
{
84+
test: /\.(woff|woff2|eot|ttf|otf)$/i,
85+
// asset 自动地在 asset/resource 和 asset/inline 之间进行选择, 默认size < 8kb 实行asset/inline
86+
type: 'asset',
87+
parser: {
88+
dataUrlCondition: {
89+
maxSize: 4 * 1024 // 4kb
90+
}
91+
},
92+
generator: {
93+
filename: 'fonts/[name].[hash][ext]',
94+
},
7595
},
76-
},
77-
{
78-
test: /\.(woff|woff2|eot|ttf|otf)$/i,
79-
// asset 自动地在 asset/resource 和 asset/inline 之间进行选择, 默认size < 8kb 实行asset/inline
80-
type: 'asset',
81-
parser: {
82-
dataUrlCondition: {
83-
maxSize: 4 * 1024 // 4kb
96+
],
97+
},
98+
plugins: [
99+
new CopyWebpackPlugin({
100+
patterns: [
101+
{
102+
from: path.resolve(__dirname, '../static'),
103+
to: path.resolve(__dirname, '../dist'),
104+
noErrorOnMissing: true
84105
}
85-
},
86-
generator: {
87-
filename: 'fonts/[name].[hash][ext]',
88-
},
89-
},
106+
]
107+
}),
108+
new ESLintPlugin(),
109+
new VueLoaderPlugin(),
110+
// 注入webpack编译时js中的全局变量
111+
new webpack.DefinePlugin({
112+
'process.env.THEME': JSON.stringify(process.env.THEME)
113+
})
90114
],
91-
},
92-
plugins: [
93-
new CopyWebpackPlugin({
94-
patterns: [
95-
{
96-
from: path.resolve(__dirname, '../static'),
97-
to: path.resolve(__dirname, '../dist'),
98-
noErrorOnMissing: true
99-
}
100-
]
101-
}),
102-
new ESLintPlugin(),
103-
new VueLoaderPlugin(),
104-
// 提取style生成 css文件
105-
new MiniCssExtractPlugin({
106-
filename: 'css/[name].[contenthash:8].css',
107-
chunkFilename: 'css/[id][contenthash:8].css',
108-
ignoreOrder: true
109-
}),
110-
// 注入webpack编译时js中的全局变量
111-
new webpack.DefinePlugin({
112-
'process.env.THEME': JSON.stringify(process.env.THEME)
113-
})
114-
],
115-
resolve: {
116-
// 路径别名以及文件默认查找后缀数组
117-
alias: {
118-
'@': path.resolve(__dirname, '../src'),
119-
'@styles': path.resolve(__dirname, '../src/styles'),
120-
'@images': path.resolve(__dirname, '../src/images'),
121-
'@theme': path.resolve(__dirname, `../src/styles/themes/${process.env.THEME}.scss`)
122-
},
123-
extensions: ['.js', '.ts', '.jsx', '.tsx', '.vue', '.json'],
124-
}
115+
resolve: {
116+
// 路径别名以及文件默认查找后缀数组
117+
alias: {
118+
'@': path.resolve(__dirname, '../src'),
119+
'@styles': path.resolve(__dirname, '../src/styles'),
120+
'@images': path.resolve(__dirname, '../src/images'),
121+
'@theme': path.resolve(__dirname, `../src/styles/themes/${process.env.THEME}.scss`)
122+
},
123+
extensions: ['.js', '.ts', '.jsx', '.tsx', '.vue', '.json'],
124+
}
125+
};
125126
};

build/webpack.client.conf.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
const webpack = require('webpack');
22
const { merge } = require('webpack-merge');
3-
const baseConfig = require('./webpack.base.conf.js');
3+
const baseConfig = require('./webpack.base.conf.js')('client');
44
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin');
55
const TerserPlugin = require('terser-webpack-plugin');
66
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
7+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
78

89
module.exports = (env) => {
910
const isProd = env.NODE_ENV === 'production';
@@ -39,6 +40,12 @@ module.exports = (env) => {
3940
mode: env.NODE_ENV,
4041
entry: './src/entry-client.js',
4142
plugins: [
43+
// 提取style生成 css文件
44+
new MiniCssExtractPlugin({
45+
filename: 'css/[name].[contenthash:8].css',
46+
chunkFilename: 'css/[id][contenthash:8].css',
47+
ignoreOrder: true
48+
}),
4249
new webpack.DefinePlugin({
4350
'process.env.VUE_ENV': '"client"'
4451
}),

build/webpack.server.conf.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const webpack = require('webpack');
22
const { merge } = require('webpack-merge');
33
const nodeExternals = require('webpack-node-externals');
4-
const baseConfig = require('./webpack.base.conf.js');
4+
const baseConfig = require('./webpack.base.conf.js')('server');
55
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin');
66

77
module.exports = (env) => {
@@ -26,12 +26,12 @@ module.exports = (env) => {
2626
// https://github.com/liady/webpack-node-externals
2727
// 外置化应用程序依赖模块。可以使服务器构建速度更快,
2828
// 并生成较小的 bundle 文件。
29-
externals: nodeExternals({
29+
externals: [nodeExternals({
3030
// 不要外置化 webpack 需要处理的依赖模块。
3131
// 你可以在这里添加更多的文件类型。例如,未处理 *.vue 原始文件,
3232
// 你还应该将修改 `global`(例如 polyfill)的依赖模块列入白名单
33-
allowlist: /\.css$/
34-
}),
33+
allowlist: [/\.s?css$/, /\?vue&type=style/]
34+
})],
3535

3636
// 这是将服务器的整个输出
3737
// 构建为单个 JSON 文件的插件。

package-lock.json

+48
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"koa-static-cache": "^5.1.4",
2828
"log4js": "^6.3.0",
2929
"lru-cache": "^6.0.0",
30+
"nprogress": "^0.2.0",
3031
"vue": "^2.6.14",
3132
"vue-router": "^3.5.3",
3233
"vue-server-renderer": "^2.6.14",
@@ -52,6 +53,7 @@
5253
"eslint-webpack-plugin": "^3.1.1",
5354
"mini-css-extract-plugin": "^2.4.5",
5455
"nodemon": "^2.0.15",
56+
"null-loader": "^4.0.1",
5557
"ora": "^6.0.1",
5658
"postcss-import": "^14.0.2",
5759
"postcss-loader": "^6.2.1",

src/entry-client.js

+11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { createApp } from './app';
2+
import NProgress from 'nprogress'; // progress bar
3+
import 'nprogress/nprogress.css'; // progress bar style
4+
5+
NProgress.configure({ showSpinner: false }); // NProgress Configuration
26

37
// 客户端特定引导逻辑……
48

@@ -55,6 +59,8 @@ router.beforeEach((to, from, next) => {
5559
const whiteList = store.state.whiteList;
5660
const loginName = store.state.loginName;
5761

62+
NProgress.start();
63+
5864
if (to.path !== '/login' && !loginName) {
5965
if (!whiteList.includes(to.path)) {
6066
return next(`/login?redirect=${to.fullPath}`);
@@ -91,4 +97,9 @@ router.beforeEach((to, from, next) => {
9197
});
9298
}
9399
});
100+
});
101+
102+
router.afterEach(() => {
103+
console.log(NProgress);
104+
NProgress.done(); // finish progress bar
94105
});

0 commit comments

Comments
 (0)