Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: split server chunk #7040

Merged
merged 103 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
264f512
feat: last step
HomyeeKing Dec 19, 2024
0f7ee36
fix: css
HomyeeKing Dec 23, 2024
b7111f9
feat: v1
HomyeeKing Jan 2, 2025
60bdcbb
feat: skip css
HomyeeKing Jan 2, 2025
252eb4b
chore: save
HomyeeKing Jan 2, 2025
fe58611
fix: external
HomyeeKing Jan 2, 2025
490e1da
fix: ci
HomyeeKing Jan 2, 2025
9d585da
chore: rm unused diff
HomyeeKing Jan 2, 2025
3f0d671
chore: lock
HomyeeKing Jan 2, 2025
a6fa7e1
chore: changeset
HomyeeKing Jan 2, 2025
8b2efbe
fix: er
HomyeeKing Jan 2, 2025
40876d5
fix: ci
HomyeeKing Jan 2, 2025
eb2e5db
feat: prepack esbuild-loader
HomyeeKing Jan 3, 2025
4ef7f8d
feat: tsconfig plugin
HomyeeKing Jan 4, 2025
6a5b317
chore: lock
HomyeeKing Jan 4, 2025
a56748b
chore: save
HomyeeKing Jan 4, 2025
4edab02
chore: save
HomyeeKing Jan 4, 2025
cc6617e
fix: err
HomyeeKing Jan 4, 2025
8ca5444
chore: revert format
HomyeeKing Jan 4, 2025
36314c5
chore: revert format
HomyeeKing Jan 4, 2025
c5df87b
fix: require is not defined
HomyeeKing Jan 6, 2025
9f32548
fix: banner maybe undefiend
HomyeeKing Jan 6, 2025
8eb8167
chore: save
HomyeeKing Jan 6, 2025
f49a02d
chore: save
HomyeeKing Jan 6, 2025
f8609f4
fix: external node builtin
HomyeeKing Jan 6, 2025
8a677be
chore: save
HomyeeKing Jan 7, 2025
22fafbe
fix: target
HomyeeKing Jan 8, 2025
1965e16
chore: save
HomyeeKing Jan 9, 2025
73e506c
fix: chunk and exports
HomyeeKing Jan 13, 2025
2ac13ec
feat: remove sourcemap comment
HomyeeKing Jan 13, 2025
fbef850
fix: sourcemap path
HomyeeKing Jan 13, 2025
f93a678
fix: assign __quickMode
HomyeeKing Jan 13, 2025
bd0faf8
feat: provider plugin
HomyeeKing Jan 14, 2025
7800077
fix: target
HomyeeKing Jan 14, 2025
ce34573
fix: no export
HomyeeKing Jan 14, 2025
579b338
fix: manifest assets
HomyeeKing Jan 15, 2025
4258ec2
feat: add minify
HomyeeKing Jan 15, 2025
e367461
feat: control minify
HomyeeKing Jan 15, 2025
9567a92
fix: hack replace
HomyeeKing Jan 15, 2025
f690570
Revert "feat: skip css"
HomyeeKing Jan 16, 2025
2a20982
feat: disable sourcemap
HomyeeKing Jan 16, 2025
b14428a
fix: jsx importSource
HomyeeKing Jan 16, 2025
a0cd991
chore: version
HomyeeKing Jan 16, 2025
6ffb452
chore: name
HomyeeKing Jan 16, 2025
af6d933
chore: sae
HomyeeKing Jan 16, 2025
50c3234
chore: save
HomyeeKing Jan 16, 2025
121348a
chore: sa
HomyeeKing Jan 16, 2025
5760e3f
chore: split
HomyeeKing Jan 16, 2025
d7827e0
chore: save
HomyeeKing Jan 16, 2025
ed0c302
feat: format alias
HomyeeKing Jan 17, 2025
2ac6d99
fix: alias
HomyeeKing Jan 17, 2025
cb689c0
feat: allow userConfig
HomyeeKing Jan 20, 2025
51182cb
chore: version
HomyeeKing Jan 20, 2025
7e62ad3
fix: err
HomyeeKing Jan 20, 2025
7c6b8a7
chore: save
HomyeeKing Jan 20, 2025
02cd737
feat: support server config
HomyeeKing Jan 21, 2025
bb08f88
chore: save
HomyeeKing Jan 22, 2025
dc44e7a
feat: call in vendor
HomyeeKing Jan 26, 2025
cb55a64
fix: runtime and writable
HomyeeKing Jan 26, 2025
bc0266a
chore: sync code
HomyeeKing Feb 6, 2025
d297a07
feat: support split by routes
HomyeeKing Feb 7, 2025
e50b1e5
feat: update Code
HomyeeKing Feb 11, 2025
eb8ee79
feat: ice/bundles
HomyeeKing Feb 11, 2025
68b1b82
fix: type
HomyeeKing Feb 11, 2025
f999e74
fix: err
HomyeeKing Feb 11, 2025
f373eeb
chore: rm unused file
HomyeeKing Feb 11, 2025
b2a6aa2
chore: rm unused
HomyeeKing Feb 11, 2025
a994968
feat: disable chunkFormat
HomyeeKing Feb 11, 2025
8d85cc3
chore: change back
HomyeeKing Feb 11, 2025
6354d1d
feat: change set
HomyeeKing Feb 11, 2025
917268e
feat: bundle all need plugin and loaders
HomyeeKing Feb 11, 2025
4b5429e
chore: changeset
HomyeeKing Feb 11, 2025
8e6ceee
feat: suppor transformInclude a array
HomyeeKing Feb 13, 2025
0017d9c
feat: handle svg and custom esbuild-loader
HomyeeKing Feb 13, 2025
8f4b5c0
feat: support handle assets
HomyeeKing Feb 13, 2025
9b0576a
feat: use esbuildMinify
HomyeeKing Feb 17, 2025
4208450
feat: minify css
HomyeeKing Feb 17, 2025
b8b4c92
chore: changeset
HomyeeKing Feb 19, 2025
e33705b
chore: changeset
HomyeeKing Feb 19, 2025
39eb3f5
chore: lock
HomyeeKing Feb 27, 2025
bc0c3a4
chore: merge code
HomyeeKing Feb 27, 2025
e140d6b
chore: rm tsconfigpahtsplugin
HomyeeKing Mar 4, 2025
c01a6ed
feat: init appconfig specify bundler
HomyeeKing Mar 4, 2025
42118c5
feat: reuse css and assets
HomyeeKing Mar 5, 2025
461d566
chore: rm
HomyeeKing Mar 5, 2025
4c76d78
feat: use webpackConfig
HomyeeKing Mar 6, 2025
120ca4f
chore: save
HomyeeKing Mar 6, 2025
c796441
chore: rm unused
HomyeeKing Mar 6, 2025
cba2712
chore: unused
HomyeeKing Mar 6, 2025
5ba15cd
chore: rm console
HomyeeKing Mar 6, 2025
f400cd3
fix: err
HomyeeKing Mar 6, 2025
e6379ab
fix: transform inlcude
HomyeeKing Mar 6, 2025
2a2457a
chore: updata lock
HomyeeKing Mar 6, 2025
ba91b2f
chore: change back
HomyeeKing Mar 6, 2025
0398bce
chore: "es-module-lexer": "1.6.0",
HomyeeKing Mar 6, 2025
a4eb5c1
chore: changeset
HomyeeKing Mar 6, 2025
d11ebcf
chore: change esbuildResult to bundleResult
HomyeeKing Mar 7, 2025
9cc9ec6
fix: use compiled webpack
HomyeeKing Mar 10, 2025
a9c825f
fix: provide plugin not works
HomyeeKing Mar 10, 2025
6fb9df4
chore: changeset
HomyeeKing Mar 10, 2025
eb7eb13
chore: rm console
HomyeeKing Mar 10, 2025
6240fd4
fix: specify target
HomyeeKing Mar 10, 2025
15f4cc7
fix: differentiate webpackTarget
HomyeeKing Mar 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/cyan-emus-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@ice/bundles': patch
'@ice/app': patch
---

@ice/app: align the output result with the former esbuild
@ice/bundles: export more webpack internal modules
7 changes: 7 additions & 0 deletions .changeset/forty-lamps-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@ice/bundles': patch
'@ice/app': patch
---

@ice/app: remove unused deps and import them from @ice/bundles
@ice/bundles: compile tsconfig-paths-webpack-plugin
5 changes: 5 additions & 0 deletions .changeset/khaki-maps-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ice/app': patch
---

rebase releast/next
7 changes: 7 additions & 0 deletions .changeset/neat-queens-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@ice/app': patch
---

feat: minify css file;
feat: change minifier from terser to esbuildMinifier.
feat: support config minify option
8 changes: 8 additions & 0 deletions .changeset/rude-games-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@ice/app': patch
---

- feat: change transformInclude to array
- fix: only treat .js as jsx
- feat: support customize webpack.module.rule
- feat: support handle assets
5 changes: 5 additions & 0 deletions .changeset/seven-rice-film.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ice/app': patch
---

refactro: reuse webpackConfig
5 changes: 5 additions & 0 deletions .changeset/spotty-otters-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ice/app': minor
---

support split server bundle
8 changes: 8 additions & 0 deletions .changeset/tidy-pets-know.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@ice/webpack-config': patch
'@ice/shared-config': patch
'@ice/app': patch
---

fix: use @ice/bundles instead of import webpack directly.
feat: support pass definitions for provide plugin.
1 change: 1 addition & 0 deletions packages/bundles/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,4 @@
"registry": "https://registry.npmjs.org/"
}
}

5 changes: 5 additions & 0 deletions packages/bundles/webpack/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ module.exports = {
SingleEntryPlugin: require('webpack/lib/SingleEntryPlugin'),
FetchCompileAsyncWasmPlugin: require('webpack/lib/web/FetchCompileAsyncWasmPlugin'),
FetchCompileWasmPlugin: require('webpack/lib/web/FetchCompileWasmPlugin'),
JavascriptModulesPlugin: require('webpack/lib/javascript/JavascriptModulesPlugin'),
StartupChunkDependenciesPlugin: require('webpack/lib/runtime/StartupChunkDependenciesPlugin'),
StartupHelpers: require('webpack/lib/javascript/StartupHelpers'),
compileBooleanMatcher: require('webpack/lib/util/compileBooleanMatcher'),
identifier: require('webpack/lib/util/identifier'),
StringXor: require('webpack/lib/util/StringXor'),
NormalModule: require('webpack/lib/NormalModule'),
EntryDependency: require('webpack/lib/dependencies/EntryDependency'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').JavascriptModulesPlugin;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').StartupChunkDependenciesPlugin;
1 change: 1 addition & 0 deletions packages/bundles/webpack/packages/StartupHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').StartupHelpers;
1 change: 1 addition & 0 deletions packages/bundles/webpack/packages/compileBooleanMatcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').compileBooleanMatcher;
1 change: 1 addition & 0 deletions packages/bundles/webpack/packages/identifier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').identifier;
2 changes: 1 addition & 1 deletion packages/ice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,4 @@
"publishConfig": {
"access": "public"
}
}
}
24 changes: 17 additions & 7 deletions packages/ice/src/requireHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,24 @@ export function getHookFiles() {
'webpack/lib/ExternalsPlugin',
'webpack/lib/web/FetchCompileAsyncWasmPlugin',
'webpack/lib/web/FetchCompileWasmPlugin',
'webpack/lib/runtime/StartupChunkDependenciesPlugin',
'webpack/lib/javascript/JavascriptModulesPlugin',
'webpack/lib/javascript/StartupHelpers',
'webpack/lib/util/identifier',
'webpack/lib/util/compileBooleanMatcher',
];
const webpackDir = path.join(require.resolve('@ice/bundles/compiled/webpack'), '../');
const pluginMap = webpackPlugins.map((pluginPath) => {
return [pluginPath, pluginPath.replace(/^webpack\/lib\/((web|node|optimize|webworker)\/)?/, webpackDir)];
return [
pluginPath,
pluginPath.replace(/^webpack\/lib\/((web|node|optimize|webworker|runtime|javascript|util)\/)?/, webpackDir),
];
});
const pluginMapWithJs = webpackPlugins.map((pluginPath) => {
return [
`${pluginPath}.js`,
pluginPath.replace(/^webpack\/lib\/((web|node|optimize|webworker|runtime|javascript|util)\/)?/, webpackDir),
];
});

return [
Expand All @@ -42,6 +56,7 @@ export function getHookFiles() {
['webpack/hot/only-dev-server', `${webpackDir}hot/only-dev-server`],
['webpack/hot/emitter', `${webpackDir}hot/emitter`],
...pluginMap,
...pluginMapWithJs,
];
}

Expand All @@ -52,12 +67,7 @@ function hijackWebpack() {
// eslint-disable-next-line global-require
const mod = require('module');
const resolveFilename = mod._resolveFilename;
mod._resolveFilename = function (
request: string,
parent: any,
isMain: boolean,
options: any,
) {
mod._resolveFilename = function (request: string, parent: any, isMain: boolean, options: any) {
const hookResolved = hookPropertyMap.get(request);
if (hookResolved) request = hookResolved;
return resolveFilename.call(mod, request, parent, isMain, options);
Expand Down
39 changes: 29 additions & 10 deletions packages/ice/src/service/serverCompiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import getCSSModuleIdent from '../utils/getCSSModuleIdent.js';
import { scanImports } from './analyze.js';
import type { PreBundleDepsMetaData } from './preBundleDeps.js';
import preBundleDeps from './preBundleDeps.js';
import { WebpackServerCompiler } from './webpackServerCompiler/compiler.js';
import VirualAssetPlugin from './webpackServerCompiler/virtualAssetPlugin.js';

const logger = createLogger('server-compiler');

Expand Down Expand Up @@ -100,7 +102,6 @@ export function createServerCompiler(options: Options) {
const externals = task.config?.externals || {};
const sourceMap = task.config?.sourceMap;
const dev = command === 'start';

// Filter empty alias.
const { ignores, alias } = filterAlias(task.config?.alias || {});

Expand Down Expand Up @@ -144,6 +145,7 @@ export function createServerCompiler(options: Options) {
redirectImports,
getRoutesFile,
}, 'esbuild', { isServer });

const define = getRuntimeDefination(task.config?.define || {}, runtimeDefineVars, transformEnv);
if (preBundle) {
const plugins = [
Expand All @@ -169,7 +171,7 @@ export function createServerCompiler(options: Options) {
plugins,
});
}

server.bundler = server.bundler ?? 'esbuild';
const format = customBuildOptions?.format || 'esm';

let buildOptions: esbuild.BuildOptions = {
Expand Down Expand Up @@ -236,35 +238,52 @@ export function createServerCompiler(options: Options) {
}

const startTime = new Date().getTime();
logger.debug('[esbuild]', `start compile for: ${JSON.stringify(buildOptions.entryPoints)}`);
logger.debug(`[${server.bundler}]`, `start compile for: ${JSON.stringify(buildOptions.entryPoints)}`);

try {
let esbuildResult: esbuild.BuildResult;
let bundleResult: any;
let context: esbuild.BuildContext;
if (dev) {
context = await esbuild.context(buildOptions);
esbuildResult = await context.rebuild();
bundleResult = await context.rebuild();
} else {
esbuildResult = await esbuild.build(buildOptions);
switch (server.bundler) {
case 'webpack':
const webpackServerCompiler = new WebpackServerCompiler({
...buildOptions,
externals,
compileIncludes: task.config.compileIncludes,
plugins: [compilationInfo && new VirualAssetPlugin({ compilationInfo, rootDir })],
rootDir,
userServerConfig: server,
runtimeDefineVars,
});
bundleResult = (await webpackServerCompiler.build())?.compilation;
break;
case 'esbuild':
default:
bundleResult = await esbuild.build(buildOptions);
break;
}
}

logger.debug('[esbuild]', `time cost: ${new Date().getTime() - startTime}ms`);
logger.debug(`[${server.bundler}]`, `time cost: ${new Date().getTime() - startTime}ms`);

const esm = server?.format === 'esm';
const outJSExtension = esm ? '.mjs' : '.cjs';
const serverEntry = path.join(rootDir, task.config.outputDir, SERVER_OUTPUT_DIR, `index${outJSExtension}`);

if (removeOutputs && esbuildResult.metafile) {
if (removeOutputs && bundleResult.metafile) {
// build/server/a.mjs -> a.mjs
const currentOutputFiles = Object.keys(esbuildResult.metafile.outputs)
const currentOutputFiles = Object.keys(bundleResult.metafile.outputs)
.map(output => output.replace(formatPath(`${path.relative(rootDir, buildOptions.outdir)}${path.sep}`), ''));
const allOutputFiles = fg.sync('**', { cwd: buildOptions.outdir });
const outdatedFiles = difference(allOutputFiles, currentOutputFiles);
outdatedFiles.forEach(outdatedFile => fse.removeSync(path.join(buildOptions.outdir, outdatedFile)));
}

return {
...esbuildResult,
...bundleResult,
context,
serverEntry,
};
Expand Down
116 changes: 116 additions & 0 deletions packages/ice/src/service/webpackServerCompiler/compiler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import path from 'path';
import { fileURLToPath } from 'url';
import webpack from '@ice/bundles/compiled/webpack/index.js';
import { getWebpackConfig } from '@ice/webpack-config';
import type { UserConfig } from '../../types/userConfig.js';
import { logger } from '../../utils/logger.js';
import { getExpandedEnvs } from '../../utils/runtimeEnv.js';
import { RUNTIME_TMP_DIR } from '../../constant.js';

const _dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));

export class WebpackServerCompiler {
private options;

constructor(options: any) {
this.options = options;
}

private async createWebpackConfig(options: {
userServerConfig: UserConfig['server'];
rootDir: string;
[key: string]: any;
}) {
const { userServerConfig } = options;
const { webpackConfig = {} } = userServerConfig;
const definitions = await this.getEsbuildInject();
return getWebpackConfig({
config: {
mode: 'production',
entry: options.entryPoints,
alias: options.alias,
webpackTarget: 'node12.20',
externalsPresets: {
node: false,
},
output: {
filename: `[name].${options.format === 'esm' ? 'mjs' : 'cjs'}`,
path: options.outdir,
// align the output with former esbuild
chunkFormat: false,
clean: true,
library: {
type: 'commonjs2',
},
...(webpackConfig.output as any),
},
plugins: [...options.plugins, ...(webpackConfig.plugins || [])] as any,
externals: options.externals,
outputDir: options.outdir,
enableCache: false,
loaders: [
// Use esbuild to compile JavaScript & TypeScript
{
// // Match `.js`, `.jsx`, `.ts` or `.tsx` files
test: /\.m?[jt]sx?$/,
use: [path.resolve(_dirname, 'removeMagicString.js')],
},
...(webpackConfig.module?.rules || []),
],
useDevServer: false,
analyzer: false,
assetsManifest: false,
define: options.define,
optimization: { ...webpackConfig.optimization } as any,
minify: options.minify,
compileIncludes: webpackConfig.transformInclude,
swcOptions: {
compilationConfig: {
jsc: {
externalHelpers: false,
transform: {
react: {
runtime: options.jsx,
importSource: '@ice/runtime/react',
},
},
},
},
},
definitions,
},
rootDir: options.rootDir,
webpack: webpack as any,
runtimeTmpDir: RUNTIME_TMP_DIR,
userConfigHash: '',
getExpandedEnvs,
isServer: true,
});
}

private async getEsbuildInject(): Promise<Record<string, string | string[]>> {
const provideRecord = {};
const allInjects = await Promise.all(this.options.inject.map((inj) => import(inj)));
allInjects.forEach((injs, index) => {
Object.keys(injs).forEach((key) => {
provideRecord[key] = [this.options.inject[index], key];
});
});
return provideRecord;
}

async build(): Promise<any> {
const config = await this.createWebpackConfig(this.options);
return new Promise((resolve, reject) => {
webpack(config as any, (err, stats) => {
if (err || stats?.hasErrors?.()) {
logger.error(err || stats.toString());
reject(err || stats.toString());
process.exit(1);
} else {
resolve(stats);
}
});
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function (source: string) {
const result = source.replace(
/webpackChunkName:\s*["'][^"']+["']/g,
'webpackMode: "eager"',
);

// Return the modified source
return result;
}
Loading