我的Aurelia应用程序正在运行默认的代码拆分,但是我的主捆绑包很大,并且我的node_modules负载也很大。我没有在文档的任何地方看到有关如何优化大型应用程序或如何仅加载对初始加载至关重要的内容以及如何基于路由加载所有其余内容的文档。我有很多代码是根据路由动态加载的,但我的初始加载大约是8mb(未解析和未压缩)。我能做什么?我可以设置任何特殊的过滤条件来进一步细分吗?
这是我的webpack配置:
import { merge } from '@easy-webpack/core';
const webpack = require('webpack');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HappyPack = require('happypack');
const path = require("path");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const { AureliaPlugin, ModuleDependenciesPlugin } = require("aurelia-webpack-plugin");
const webpackPort = parseInt(process.env.WEBPACK_PORT) || 9000;
const webpackHost = process.env.WEBPACK_HOST || 'localhost';
const ENV = process.env.NODE_ENV && process.env.NODE_ENV.toLowerCase() || (process.env.NODE_ENV = 'local');
const isHMR = process.argv.join('').indexOf('hot') > -1 || !!process.env.WEBPACK_HMR;
const title = 'My site';
const baseUrl = '/';
const rootDir = __dirname;
const extractCSS = new ExtractTextPlugin({
"filename" : '[name]-css.css'
});
const extractLESS = new ExtractTextPlugin({
"filename" : '[name]-less.css'
});
let plugins = [
new HappyPack({
"id" : "css1",
"loaders" : ['css-loader']
}),
new HappyPack({
"id" : "css2",
"loaders" : ['style-loader', 'css-loader']
}),
new HappyPack({
"id" : "less1",
"loaders" : ['css-loader', 'less-loader']
}),
new HappyPack({
"id" : "less2",
"loaders" : ['style-loader', 'css-loader', 'less-loader']
}),
new HappyPack({
"id" : "ts",
"threads" : 2,
"loaders" : [{
"path" : "ts-loader",
"query" : {
happyPackMode: true
}
}]
}),
new HappyPack({
"id" : "js",
"loaders" : ['babel-loader']
}),
new AureliaPlugin(),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
'Promise': 'bluebird',
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new ModuleDependenciesPlugin({
"au-table": [ './au-table', './au-table-pagination', './au-table-pagination.html', './au-table-select', './au-table-sort' ],
"aurelia-authentication": ["./authFilterValueConverter", "./authenticatedFilterValueConverter", "./authenticatedValueConverter" ],
"aurelia-mdl-plugin" : ['./mdl'],
"aurelia-froala-editor": [ './froala-editor' ],
}),
//new HardSourceWebpackPlugin()
];
plugins.push(extractCSS);
plugins.push(extractLESS);
let base = {
entry: {
main: [
'aurelia-bootstrapper',
]
},
output: {
path: path.resolve(__dirname, "dist_"+process.env.NODE_ENV.toLowerCase()),
publicPath: baseUrl,
},
resolve: {
extensions: [".ts", ".js"],
modules: ["src", "node_modules", 'kendo/js'],
symlinks: false,
},
module: {
rules: [
{
test: /\.css$/i,
issuer: [{ not: [{ test: /\.html$/i }] }],
use: (ENV !== 'local') ? extractCSS.extract({
fallback: 'style-loader',
use: 'happypack/loader?id=css1',
})
: 'happypack/loader?id=css2'
},
{
test: /\.css$/i,
issuer: [{ test: /\.html$/i }],
// CSS required in templates cannot be extracted safely
// because Aurelia would try to require it again in runtime
use: 'happypack/loader?id=css1'
},
{
test: /\.less$/i,
use: 'happypack/loader?id=less2',
// (ENV !== 'local') ? extractLESS.extract({
// fallback: 'style-loader',
// use: 'happypack/loader?id=less1',
// })
// : 'happypack/loader?id=less2',
issuer: {
// only when the issuer is a .js/.ts file, so the loaders are not applied inside templates
test: /\.[tj]s$/i,
}
},
{
test: /\.ts$/i,
use: 'happypack/loader?id=ts',
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components|src)/,
use: 'happypack/loader?id=js',
},
{
test: /\.html$/i, use: ["html-loader"]
},
{
test: /\.mp4$/,
loader: 'url-loader?limit=100000&mimetype=video/mp4'
},
{
test: /\.ogv$/,
loader: 'url-loader?limit=100000&mimetype=video/ogv'
},
{
test: /[\/\\]node_modules[\/\\]bluebird[\/\\].+\.js$/,
loader: 'expose-loader?Promise'
},
{
test: /\.json$/, loader: 'json-loader'
}
]
},
plugins: plugins
}
const local = {
mode: 'development',
output: {
filename: '[name].[chunkhash].bundle.js',
sourceMapFilename: '[name].[chunkhash].bundle.map',
chunkFilename: '[id].[chunkhash].chunk.js'
},
devServer: {
port: webpackPort,
host: '0.0.0.0',
historyApiFallback: true,
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
},
}
const production = {
mode: 'production',
//devtool: '#source-map',
optimization: {
splitChunks: {
cacheGroups: {
node_vendors: {
test: /[\\/]node_modules[\\/]/,
chunks: "all",
priority: 1
}
// default: false,
// commons: {
// name: 'commons',
// chunks: 'initial',
// minChunks: 2
// }
// commons: {
// test: /[\\/]node_modules[\\/]/,
// name: "vendor",
// chunks: "all"
// }
}
}
},
output: {
filename: '[name].[chunkhash].bundle.js',
sourceMapFilename: '[name].[chunkhash].bundle.map',
chunkFilename: '[id].[chunkhash].chunk.js'
},
plugins: [
new BundleAnalyzerPlugin(),
]
}
const variables = {
plugins: [
new CleanWebpackPlugin(path.resolve(__dirname, "dist_"+process.env.NODE_ENV.toLowerCase()), {"verbose" : false}),
// literally replaces all mentions of a given variable in your code with the given value
new DefinePlugin({
ENV: JSON.stringify(ENV),
HMR: isHMR,
'process.env': {
NODE_ENV: JSON.stringify(ENV),
HMR: isHMR,
WEBPACK_PORT: JSON.stringify(webpackPort),
WEBPACK_HOST: JSON.stringify(webpackHost),
VERSION: JSON.stringify(process.env.npm_package_appversion),
BUILD: JSON.stringify(process.env.npm_package_build),
BRANCH: JSON.stringify(process.env.NODE_ENV.toLowerCase())
}
})
]
}
const fontsAndImages = {
module: {
rules: [
// embed small images and fonts as Data Urls and larger ones as files
{ test: /\.(png|gif|jpg)$/, loader: 'url-loader', options: { limit: 8192 } },
{ test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
{ test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
{ test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader' },
]
}
}
const generateIndexHtml = {
plugins: [
new HtmlWebpackPlugin({
template: 'index.ejs',
chunksSortMode: 'dependency',
minify: ENV === 'prod' ? {
removeComments: true,
collapseWhitespace: true
}
: undefined,
metadata:
{
title, ENV, isHMR
}
})
]
}
const copyFiles = {
plugins: [
new CopyWebpackPlugin([
{ from: 'favicon.png', to: 'favicon.png' },
{ from: 'apple-touch-icon.png', to: 'apple-touch-icon.png' },
{ from: 'manifest.json', to: 'manifest.json' },
{ from: 'src/main.css', to: 'src/main.css' },
{ from: 'images/**/*'},
{ from: 'widget/**/*'},
{ from: 'notifications-sw.js', to: 'notifications-sw.js' },
])
]
}
const config = merge(
base,
ENV === 'prod' || ENV === 'stage' || ENV === 'qa' || ENV === 'dev' ? production : local,
variables,
fontsAndImages,
generateIndexHtml,
...(
ENV === 'prod' || ENV === 'stage' || ENV === 'qa' || ENV === 'dev' ? [copyFiles] : []
),
)
module.exports = config;