我已经构建了一个 spa react 应用程序,下面是该应用程序的 index.html
有 2 个应用程序,app1 和 app2,app1 最初加载,app2 仅在需要时加载
index.html 用于 app1 和 app2 的单个 spa 配置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=9;IE=10;IE=Edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Project</title>
<!-- app2 css -->
<link href='http://localhost:8003/app2.css' rel='stylesheet'/>
</head>
<body>
<script>
function randstr(prefix) {
return Math.random().toString(36).replace('0.', prefix || '');
}
var suffix = randstr('?v=');
document.write('<script src="config/config.js' + suffix + '"><\/script>');
document.write('<script type="systemjs-importmap" crossorigin="anonymous">' +
'{ \n"imports": {\n' +
' "@portal/config": "http://localhost:8001/index.js' + '",\n' +
' "@portal/app1": "http://localhost:8002/app1.js' + '",\n' + // this loads first, it has login page
' "@portal/app2": "http://localhost:8003/app2.js' + '" \n }\n}' + // app 2 which loads on click
'<\/script>');
</script>
<!-- load the vendor chunk of app2-->
<script src='http://localhost:8003/vendor.app2.js'></script>
<!-- Load the common deps-->
<script>
imports and loads dependencies of react, react-dom, lodash and others
</script>
<!-- Load the application -->
<script>
SystemJS.import('@portal/config')
</script>
<div id="app" class="site-container"></div>
</body>
</html>
在上面的 index.html 中,通过 systemjs-importmap 配置了应用程序,一切正常。
正如您在 importmap 中看到的,导入 app2("@portal/app2": "http://localhost:8003/app2.js'),这只会在需要时加载,但这个包有点大,我有试图通过提取css和供应商块来提高性能,缩小js和css,这确实提高了性能,这些脚本也被添加了(http://localhost:8003/vendor.app2.js,http://本地主机:8003/app2.css)
app2 的 webpack.config.js
const webpack = require('webpack')
const path = require('path')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/app2.js'),
output: {
filename: 'app2.js',
library: 'app2',
libraryTarget: 'amd',
path: path.resolve(__dirname, 'build/app2'),
},
mode: 'production',
module: {
rules: [
{parser: {System: false}},
{
test: /\.js$/,
exclude: [path.resolve(__dirname, 'node_modules')],
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env"]
}
},
{
test: /\.krem.css$/,
exclude: [path.resolve(__dirname, 'node_modules')],
use: [
{
loader: 'kremling-loader',
options: {
namespace: 'app2',
postcss: {
plugins: {
'autoprefixer': {},
},
},
},
},
],
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader' },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader' },
// { test: /\.css$/, loader: "style-loader!css-loader"},
{ test: /\.css$/, use: [
MiniCssExtractPlugin.loader,
'css-loader',
]},
],
},
plugins: [
new CleanWebpackPlugin({
verbose: true,
cleanOnceBeforeBuildPatterns: [path.resolve(__dirname, 'build/app2')],
}),
new CopyWebpackPlugin({
patterns: [
{from: path.resolve(__dirname, 'src/ppsr.js')},
]}),
new TerserPlugin({
parallel: true,
cache: true
}),
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'all',
reuseExistingChunk: true,
priority: 1,
test: module =>
/[\\/]node_modules[\\/]/.test(module.context),
minChunks: 1,
minSize: 0,
},
},
},
minimize: true,
minimizer: [
new CssMinimizerPlugin(),
],
},
devtool: 'source-map',
externals: [
/^@portal\/*/,
/^lodash$/,
/^single-spa$/,
/^rxjs\/?.*$/,
/^react$/,
/^react\/lib.*/,
/^react-dom$/,
/.*react-dom.*/,
],
}
我得到了构建文件 vendor.app2.css、app2.css、app2.js 文件...仅在需要时加载 js,因为它是由 importmap 导入的,并且 css 和供应商位于全局空间中(意味着加载与 app2 无关加载与否)
问题: 如何仅在单个 spa 反应中需要时加载与 app2 的 js 相同的供应商和 CSS?