mirror of
https://github.com/strapi/strapi.git
synced 2025-08-28 10:45:51 +00:00
Merge pull request #12882 from strapi/enhancement/speed-up-webpack
Enhancement/speed up webpack
This commit is contained in:
commit
2627aa6ee2
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "getstarted",
|
||||
"private": true,
|
||||
"version": "4.2.0-beta.0",
|
||||
"version": "4.1.4",
|
||||
"description": "A Strapi application.",
|
||||
"scripts": {
|
||||
"develop": "strapi develop",
|
||||
|
@ -28,6 +28,7 @@
|
||||
"develop:webpack": "cross-env NODE_ENV=development webpack serve --config webpack.config.dev.js --progress profile",
|
||||
"prepublishOnly": "yarn build",
|
||||
"build": "rimraf build && node ./scripts/build.js",
|
||||
"build:mesure": "rimraf build && cross-env MESURE_BUILD_SPEED=true node ./scripts/build.js",
|
||||
"test": "echo \"no tests yet\"",
|
||||
"test:unit": "jest --verbose",
|
||||
"test:front": "cross-env IS_EE=true jest --config ./jest.config.front.js",
|
||||
@ -37,10 +38,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.16.7",
|
||||
"@babel/plugin-proposal-async-generator-functions": "7.16.7",
|
||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.16.7",
|
||||
"@babel/plugin-transform-runtime": "7.16.7",
|
||||
"@babel/preset-env": "7.16.7",
|
||||
"@babel/preset-react": "7.16.7",
|
||||
@ -131,7 +128,6 @@
|
||||
"sift": "13.5.0",
|
||||
"style-loader": "3.3.1",
|
||||
"styled-components": "^5.2.3",
|
||||
"terser-webpack-plugin": "5.3.0",
|
||||
"webpack": "5.65.0",
|
||||
"webpack-cli": "4.9.1",
|
||||
"webpack-dev-server": "4.7.3",
|
||||
@ -140,6 +136,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"duplicate-dependencies-webpack-plugin": "0.2.0",
|
||||
"speed-measure-webpack-plugin": "1.5.0",
|
||||
"webpack-bundle-analyzer": "4.4.1"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
|
||||
|
||||
const webpackConfig = require('../webpack.config');
|
||||
const getPluginsPath = require('../utils/get-plugins-path');
|
||||
const {
|
||||
getCorePluginsPath,
|
||||
getPluginToInstallPath,
|
||||
@ -11,20 +14,24 @@ const {
|
||||
|
||||
const PLUGINS_TO_INSTALL = ['i18n', 'users-permissions'];
|
||||
|
||||
// Wrapper that outputs the webpack speed
|
||||
const smp = new SpeedMeasurePlugin();
|
||||
|
||||
const buildAdmin = async () => {
|
||||
const entry = path.join(__dirname, '..', 'admin', 'src');
|
||||
const dest = path.join(__dirname, '..', 'build');
|
||||
const corePlugins = getCorePluginsPath();
|
||||
const plugins = getPluginToInstallPath(PLUGINS_TO_INSTALL);
|
||||
const allPlugins = { ...corePlugins, ...plugins };
|
||||
const pluginsPath = getPluginsPath();
|
||||
|
||||
await createPluginsFile(allPlugins);
|
||||
|
||||
const args = {
|
||||
entry,
|
||||
dest,
|
||||
cacheDir: __dirname,
|
||||
pluginsPath: [path.resolve(__dirname, '../../../../packages')],
|
||||
cacheDir: path.join(__dirname, '..'),
|
||||
pluginsPath,
|
||||
env: 'production',
|
||||
optimize: true,
|
||||
options: {
|
||||
@ -33,7 +40,10 @@ const buildAdmin = async () => {
|
||||
},
|
||||
};
|
||||
|
||||
const compiler = webpack(webpackConfig(args));
|
||||
const config =
|
||||
process.env.MESURE_BUILD_SPEED === 'true' ? smp.wrap(webpackConfig(args)) : webpackConfig(args);
|
||||
|
||||
const compiler = webpack(config);
|
||||
|
||||
console.log('Building the admin panel');
|
||||
|
||||
@ -73,7 +83,7 @@ buildAdmin()
|
||||
.then(() => {
|
||||
process.exit();
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
23
packages/core/admin/utils/__tests__/get-plugins-path.test.js
Normal file
23
packages/core/admin/utils/__tests__/get-plugins-path.test.js
Normal file
@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
const getPluginsPath = require('../get-plugins-path');
|
||||
|
||||
describe('getPluginsPath', () => {
|
||||
test('should return an array of directories that contains an admin/src/index.js file', () => {
|
||||
const results = getPluginsPath();
|
||||
|
||||
expect(results.length).toBeGreaterThan(0);
|
||||
// Test that the content-type-builder is included
|
||||
expect(results.findIndex(p => p.includes('/core/content-type-builder/admin'))).not.toEqual(-1);
|
||||
// Test that the upload is included
|
||||
expect(results.findIndex(p => p.includes('/core/upload/admin'))).not.toEqual(-1);
|
||||
// Test that the documentation is included
|
||||
expect(results.findIndex(p => p.includes('/plugins/documentation/admin'))).not.toEqual(-1);
|
||||
// Test that the CM is not included
|
||||
expect(results.findIndex(p => p.includes('/core/content-manager/admin'))).toEqual(-1);
|
||||
// Test that the admin package is not included
|
||||
expect(results.findIndex(p => p.includes('/core/admin/admin'))).toEqual(-1);
|
||||
// Test that the helper-plugin package is not included
|
||||
expect(results.findIndex(p => p.includes('helper-plugin'))).toEqual(-1);
|
||||
});
|
||||
});
|
26
packages/core/admin/utils/get-plugins-path.js
Normal file
26
packages/core/admin/utils/get-plugins-path.js
Normal file
@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
const { join, resolve } = require('path');
|
||||
const fs = require('fs-extra');
|
||||
// eslint-disable-next-line node/no-extraneous-require
|
||||
const glob = require('glob');
|
||||
|
||||
const getPluginsPath = () => {
|
||||
const rootPath = resolve(__dirname, '..', join('..', '..', '..', 'packages'));
|
||||
const corePath = join(rootPath, 'core', '*');
|
||||
const pluginsPath = join(rootPath, 'plugins', '*');
|
||||
const corePackageDirs = glob.sync(corePath);
|
||||
const pluginsPackageDirs = glob.sync(pluginsPath);
|
||||
|
||||
const packageDirs = [...corePackageDirs, ...pluginsPackageDirs].filter(dir => {
|
||||
const isCoreAdmin = dir.includes('packages/core/admin');
|
||||
const pathToEntryPoint = join(dir, 'admin', 'src', 'index.js');
|
||||
const doesAdminFolderExist = fs.pathExistsSync(pathToEntryPoint);
|
||||
|
||||
return !isCoreAdmin && doesAdminFolderExist;
|
||||
});
|
||||
|
||||
return packageDirs.map(dir => resolve(__dirname, '..', join(dir, 'admin', 'src')));
|
||||
};
|
||||
|
||||
module.exports = getPluginsPath;
|
@ -3,7 +3,7 @@
|
||||
const path = require('path');
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
const { DuplicateReporterPlugin } = require('duplicate-dependencies-webpack-plugin');
|
||||
|
||||
const getPluginsPath = require('./utils/get-plugins-path');
|
||||
const webpackConfig = require('./webpack.config');
|
||||
|
||||
module.exports = () => {
|
||||
@ -19,11 +19,12 @@ module.exports = () => {
|
||||
backend: 'http://localhost:1337',
|
||||
adminPath: '/admin/',
|
||||
};
|
||||
const pluginsPath = getPluginsPath();
|
||||
|
||||
const args = {
|
||||
entry,
|
||||
cacheDir: __dirname,
|
||||
pluginsPath: [path.resolve(__dirname, '../../../packages')],
|
||||
pluginsPath,
|
||||
dest,
|
||||
env,
|
||||
options,
|
||||
@ -41,27 +42,6 @@ module.exports = () => {
|
||||
|
||||
return {
|
||||
...config,
|
||||
snapshot: {
|
||||
managedPaths: [
|
||||
path.resolve(__dirname, '../content-type-builder'),
|
||||
path.resolve(__dirname, '../upload'),
|
||||
path.resolve(__dirname, '../helper-plugin'),
|
||||
],
|
||||
buildDependencies: {
|
||||
hash: true,
|
||||
timestamp: true,
|
||||
},
|
||||
module: {
|
||||
timestamp: true,
|
||||
},
|
||||
resolve: {
|
||||
timestamp: true,
|
||||
},
|
||||
resolveBuildDependencies: {
|
||||
hash: true,
|
||||
timestamp: true,
|
||||
},
|
||||
},
|
||||
|
||||
devServer: {
|
||||
port: 4000,
|
||||
|
@ -1,14 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const fse = require('fs-extra');
|
||||
const webpack = require('webpack');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const { ESBuildMinifyPlugin } = require('esbuild-loader');
|
||||
const WebpackBar = require('webpackbar');
|
||||
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
|
||||
const isWsl = require('is-wsl');
|
||||
const alias = require('./webpack.alias');
|
||||
const getClientEnvironment = require('./env');
|
||||
|
||||
@ -79,6 +79,11 @@ module.exports = ({
|
||||
});
|
||||
}
|
||||
|
||||
// Directly inject a polyfill in the webpack entry point before the entry point
|
||||
// FIXME: I have noticed a bug regarding the helper-plugin and esbuild-loader
|
||||
// The only I could fix it was to inject the babel polyfill
|
||||
const babelPolyfill = '@babel/polyfill/dist/polyfill.min.js';
|
||||
|
||||
return {
|
||||
mode: isProduction ? 'production' : 'development',
|
||||
bail: isProduction ? true : false,
|
||||
@ -86,7 +91,7 @@ module.exports = ({
|
||||
experiments: {
|
||||
topLevelAwait: true,
|
||||
},
|
||||
entry,
|
||||
entry: [babelPolyfill, entry],
|
||||
output: {
|
||||
path: dest,
|
||||
publicPath: options.adminPath,
|
||||
@ -98,28 +103,9 @@ module.exports = ({
|
||||
optimization: {
|
||||
minimize: optimize,
|
||||
minimizer: [
|
||||
// Copied from react-scripts
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
parse: {
|
||||
ecma: 8,
|
||||
},
|
||||
compress: {
|
||||
ecma: 5,
|
||||
warnings: false,
|
||||
comparisons: false,
|
||||
inline: 2,
|
||||
},
|
||||
mangle: {
|
||||
safari10: true,
|
||||
},
|
||||
output: {
|
||||
ecma: 5,
|
||||
comments: false,
|
||||
ascii_only: true,
|
||||
},
|
||||
},
|
||||
parallel: !isWsl,
|
||||
new ESBuildMinifyPlugin({
|
||||
target: 'es2015',
|
||||
css: true, // Apply minification to CSS assets
|
||||
}),
|
||||
],
|
||||
runtimeChunk: true,
|
||||
@ -128,41 +114,79 @@ module.exports = ({
|
||||
rules: [
|
||||
{
|
||||
test: /\.m?js$/,
|
||||
// TODO remove when plugins are built separately
|
||||
include: [cacheDir, ...pluginsPath],
|
||||
use: {
|
||||
loader: require.resolve('babel-loader'),
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
cacheCompression: isProduction,
|
||||
compact: isProduction,
|
||||
presets: [
|
||||
require.resolve('@babel/preset-env'),
|
||||
require.resolve('@babel/preset-react'),
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
require.resolve('@strapi/babel-plugin-switch-ee-ce'),
|
||||
{
|
||||
// Imported this tells the custom plugin where to look for the ee folder
|
||||
roots,
|
||||
},
|
||||
],
|
||||
require.resolve('@babel/plugin-proposal-class-properties'),
|
||||
require.resolve('@babel/plugin-syntax-dynamic-import'),
|
||||
require.resolve('@babel/plugin-transform-modules-commonjs'),
|
||||
require.resolve('@babel/plugin-proposal-async-generator-functions'),
|
||||
include: cacheDir,
|
||||
oneOf: [
|
||||
// Use babel-loader for files that distinct the ee and ce code
|
||||
// These files have an import Something from 'ee_else_ce/
|
||||
{
|
||||
test(filePath) {
|
||||
if (!filePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
[
|
||||
require.resolve('@babel/plugin-transform-runtime'),
|
||||
{
|
||||
// absoluteRuntime: true,s
|
||||
helpers: true,
|
||||
regenerator: true,
|
||||
},
|
||||
],
|
||||
[require.resolve('babel-plugin-styled-components'), { pure: true }],
|
||||
],
|
||||
try {
|
||||
const fileContent = fse.readFileSync(filePath).toString();
|
||||
|
||||
if (fileContent.match(/from.* ['"]ee_else_ce\//)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
use: {
|
||||
loader: require.resolve('babel-loader'),
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
cacheCompression: isProduction,
|
||||
compact: isProduction,
|
||||
presets: [
|
||||
require.resolve('@babel/preset-env'),
|
||||
require.resolve('@babel/preset-react'),
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
require.resolve('@strapi/babel-plugin-switch-ee-ce'),
|
||||
{
|
||||
// Imported this tells the custom plugin where to look for the ee folder
|
||||
roots,
|
||||
},
|
||||
],
|
||||
|
||||
[
|
||||
require.resolve('@babel/plugin-transform-runtime'),
|
||||
{
|
||||
helpers: true,
|
||||
regenerator: true,
|
||||
},
|
||||
],
|
||||
[require.resolve('babel-plugin-styled-components'), { pure: true }],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
// Use esbuild-loader for the other files
|
||||
{
|
||||
use: {
|
||||
loader: require.resolve('esbuild-loader'),
|
||||
options: {
|
||||
loader: 'jsx',
|
||||
target: 'es2015',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.m?js$/,
|
||||
include: pluginsPath,
|
||||
use: {
|
||||
loader: require.resolve('esbuild-loader'),
|
||||
options: {
|
||||
loader: 'jsx',
|
||||
target: 'es2015',
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -212,8 +236,6 @@ module.exports = ({
|
||||
new HtmlWebpackPlugin({
|
||||
inject: true,
|
||||
template: path.resolve(__dirname, 'index.html'),
|
||||
// FIXME
|
||||
// favicon: path.resolve(__dirname, 'admin/src/favicon.ico'),
|
||||
}),
|
||||
new webpack.DefinePlugin(envVariables),
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
}
|
||||
],
|
||||
"main": "build/index.js",
|
||||
"module": "lib/src/index.js",
|
||||
"files": [
|
||||
"build"
|
||||
],
|
||||
|
@ -20922,6 +20922,13 @@ specificity@^0.4.1:
|
||||
resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019"
|
||||
integrity sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==
|
||||
|
||||
speed-measure-webpack-plugin@1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.5.0.tgz#caf2c5bee24ab66c1c7c30e8daa7910497f7681a"
|
||||
integrity sha512-Re0wX5CtM6gW7bZA64ONOfEPEhwbiSF/vz6e2GvadjuaPrQcHTQdRGsD8+BE7iUOysXH8tIenkPCQBEcspXsNg==
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
|
||||
split-array-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/split-array-stream/-/split-array-stream-2.0.0.tgz#85a4f8bfe14421d7bca7f33a6d176d0c076a53b1"
|
||||
|
Loading…
x
Reference in New Issue
Block a user