@teambit/react 0.0.806 → 0.0.807
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/web/compute-results.ts +3 -1
- package/apps/web/react-app-options.ts +5 -0
- package/apps/web/react-build-result.ts +1 -0
- package/apps/web/react.app-type.ts +1 -0
- package/apps/web/react.application.ts +61 -83
- package/apps/web/webpack/mutators.ts +68 -0
- package/apps/web/webpack/webpack.app.ssr.config.ts +24 -0
- package/artifacts/__bit_junit.xml +2 -2
- package/artifacts/env-template/public/{486.b4b503d786c3da312ae2.js → 502.1f3ad81d16d1a387ed6e.js} +2 -2
- package/artifacts/env-template/public/assets-manifest.json +12 -12
- package/artifacts/env-template/public/{compositions.70af3ab69b596fbcea59.js → compositions.1a2eae0121924a2382b5.js} +1 -1
- package/artifacts/env-template/public/compositions.html +1 -1
- package/artifacts/env-template/public/overview.4c90e935a13e148728cc.js +1 -0
- package/artifacts/env-template/public/overview.html +1 -1
- package/artifacts/env-template/public/{peers.3e4ebdb2b1709b453faa.js → peers.9bf322cedc753fa8456b.js} +1 -1
- package/artifacts/env-template/public/{preview-root.d61559bc7b06d0456acb.js → preview-root.6f380ef699dc27c5b1d6.js} +1 -1
- package/artifacts/env-template/public/static/css/{486.f6840c3e.css → 502.f6840c3e.css} +0 -0
- package/artifacts/preview/teambit_react_react-preview.js +1 -1
- package/{compositions-1659497571327.js → compositions-1659583874630.js} +0 -0
- package/dist/apps/web/compute-results.d.ts +2 -1
- package/dist/apps/web/compute-results.js +3 -1
- package/dist/apps/web/compute-results.js.map +1 -1
- package/dist/apps/web/react-app-options.d.ts +4 -0
- package/dist/apps/web/react-app-options.js.map +1 -1
- package/dist/apps/web/react-build-result.d.ts +1 -0
- package/dist/apps/web/react-build-result.js.map +1 -1
- package/dist/apps/web/react.app-type.js +1 -1
- package/dist/apps/web/react.app-type.js.map +1 -1
- package/dist/apps/web/react.application.d.ts +7 -3
- package/dist/apps/web/react.application.js +62 -95
- package/dist/apps/web/react.application.js.map +1 -1
- package/dist/apps/web/webpack/mutators.d.ts +3 -0
- package/dist/apps/web/webpack/mutators.js +90 -0
- package/dist/apps/web/webpack/mutators.js.map +1 -1
- package/dist/apps/web/webpack/webpack.app.ssr.config.d.ts +6 -0
- package/dist/apps/web/webpack/webpack.app.ssr.config.js +29 -0
- package/dist/apps/web/webpack/webpack.app.ssr.config.js.map +1 -1
- package/dist/webpack/webpack.config.base.js +15 -1
- package/dist/webpack/webpack.config.base.js.map +1 -1
- package/{overview-1659497571327.js → overview-1659583874630.js} +0 -0
- package/package-tar/teambit-react-0.0.807.tgz +0 -0
- package/package.json +32 -30
- package/{preview-1659497571327.js → preview-1659583874630.js} +2 -2
- package/webpack/webpack.config.base.ts +2 -1
- package/artifacts/env-template/public/overview.a0492e6adc2d378a78cf.js +0 -1
- package/package-tar/teambit-react-0.0.806.tgz +0 -0
|
@@ -3,15 +3,17 @@ import { ReactAppBuildResult } from './react-build-result';
|
|
|
3
3
|
|
|
4
4
|
type resultsOptions = {
|
|
5
5
|
publicDir: string;
|
|
6
|
+
ssrPublicDir?: string;
|
|
6
7
|
};
|
|
7
8
|
export async function computeResults(
|
|
8
9
|
results: BundlerResult[],
|
|
9
|
-
{ publicDir }: resultsOptions
|
|
10
|
+
{ publicDir, ssrPublicDir }: resultsOptions
|
|
10
11
|
): Promise<ReactAppBuildResult> {
|
|
11
12
|
const result = results[0];
|
|
12
13
|
|
|
13
14
|
return {
|
|
14
15
|
publicDir,
|
|
16
|
+
ssrPublicDir,
|
|
15
17
|
errors: result.errors,
|
|
16
18
|
warnings: result.warnings,
|
|
17
19
|
};
|
|
@@ -3,8 +3,7 @@ import { Application, AppContext, AppBuildContext, AppResult } from '@teambit/ap
|
|
|
3
3
|
import type { Bundler, DevServer, BundlerContext, DevServerContext, BundlerHtmlConfig } from '@teambit/bundler';
|
|
4
4
|
import { Port } from '@teambit/toolbox.network.get-port';
|
|
5
5
|
import type { Logger } from '@teambit/logger';
|
|
6
|
-
import
|
|
7
|
-
import TerserPlugin from 'terser-webpack-plugin';
|
|
6
|
+
import compact from 'lodash.compact';
|
|
8
7
|
import { WebpackConfigTransformer } from '@teambit/webpack';
|
|
9
8
|
import { BitError } from '@teambit/bit-error';
|
|
10
9
|
import { ReactEnv } from '../../react.env';
|
|
@@ -14,8 +13,8 @@ import { ReactAppPrerenderOptions } from './react-app-options';
|
|
|
14
13
|
import { html } from '../../webpack';
|
|
15
14
|
import { ReactDeployContext } from '.';
|
|
16
15
|
import { computeResults } from './compute-results';
|
|
17
|
-
import { clientConfig, ssrConfig, calcOutputPath } from './webpack/webpack.app.ssr.config';
|
|
18
|
-
import { addDevServer, setOutput } from './webpack/mutators';
|
|
16
|
+
import { clientConfig, ssrConfig, calcOutputPath, ssrBuildConfig, buildConfig } from './webpack/webpack.app.ssr.config';
|
|
17
|
+
import { addDevServer, setOutput, replaceTerserPlugin } from './webpack/mutators';
|
|
19
18
|
import { createExpressSsr, loadSsrApp, parseAssets } from './ssr/ssr-express';
|
|
20
19
|
|
|
21
20
|
export class ReactApp implements Application {
|
|
@@ -27,6 +26,7 @@ export class ReactApp implements Application {
|
|
|
27
26
|
private reactEnv: ReactEnv,
|
|
28
27
|
readonly prerender?: ReactAppPrerenderOptions,
|
|
29
28
|
readonly bundler?: Bundler,
|
|
29
|
+
readonly ssrBundler?: Bundler,
|
|
30
30
|
readonly devServer?: DevServer,
|
|
31
31
|
readonly transformers: WebpackConfigTransformer[] = [],
|
|
32
32
|
readonly deploy?: (context: ReactDeployContext) => Promise<void>,
|
|
@@ -35,6 +35,7 @@ export class ReactApp implements Application {
|
|
|
35
35
|
) {}
|
|
36
36
|
readonly applicationType = 'react-common-js';
|
|
37
37
|
readonly dir = 'public';
|
|
38
|
+
readonly ssrDir = 'ssr';
|
|
38
39
|
|
|
39
40
|
async run(context: AppContext): Promise<number> {
|
|
40
41
|
const [from, to] = this.portRange;
|
|
@@ -163,23 +164,71 @@ export class ReactApp implements Application {
|
|
|
163
164
|
const bundler = await this.getBundler(context);
|
|
164
165
|
const bundleResult = await bundler.run();
|
|
165
166
|
|
|
166
|
-
|
|
167
|
+
if (this.ssr) {
|
|
168
|
+
const bunlder = await this.getSsrBundler(context);
|
|
169
|
+
await bunlder.run();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return computeResults(bundleResult, {
|
|
173
|
+
publicDir: `${this.getPublicDir(context.artifactsDir)}/${this.dir}`,
|
|
174
|
+
ssrPublicDir: this.ssr ? `${this.getPublicDir(context.artifactsDir)}/${this.ssrDir}` : undefined,
|
|
175
|
+
});
|
|
167
176
|
}
|
|
168
177
|
|
|
169
178
|
private getBundler(context: AppBuildContext) {
|
|
170
179
|
if (this.bundler) return this.bundler;
|
|
171
180
|
return this.getDefaultBundler(context);
|
|
172
181
|
}
|
|
173
|
-
|
|
182
|
+
|
|
183
|
+
private getSsrBundler(context: AppBuildContext) {
|
|
184
|
+
if (this.ssrBundler) return this.ssrBundler;
|
|
185
|
+
return this.getDefaultSsrBundler(context);
|
|
186
|
+
}
|
|
187
|
+
|
|
174
188
|
private async getDefaultBundler(context: AppBuildContext) {
|
|
175
189
|
const { capsule } = context;
|
|
176
|
-
const reactEnv: ReactEnv = context.env as ReactEnv;
|
|
177
190
|
const publicDir = this.getPublicDir(context.artifactsDir);
|
|
178
191
|
const outputPath = join(capsule.path, publicDir);
|
|
192
|
+
|
|
193
|
+
const bundlerContext = await this.getBuildContext(context, { outputPath });
|
|
194
|
+
const transformers: WebpackConfigTransformer[] = compact([
|
|
195
|
+
(configMutator) => configMutator.merge(buildConfig({ outputPath: join(outputPath, this.dir) })),
|
|
196
|
+
(config) => {
|
|
197
|
+
if (this.prerender) config.addPlugin(prerenderPlugin(this.prerender));
|
|
198
|
+
return config;
|
|
199
|
+
},
|
|
200
|
+
replaceTerserPlugin({ prerender: !!this.prerender }),
|
|
201
|
+
...this.transformers,
|
|
202
|
+
]);
|
|
203
|
+
|
|
204
|
+
const reactEnv = context.env as ReactEnv;
|
|
205
|
+
const bundler: Bundler = await reactEnv.getBundler(bundlerContext, transformers);
|
|
206
|
+
return bundler;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private async getDefaultSsrBundler(context: AppBuildContext) {
|
|
210
|
+
const { capsule } = context;
|
|
211
|
+
const publicDir = this.getPublicDir(context.artifactsDir);
|
|
212
|
+
const outputPath = join(capsule.path, publicDir);
|
|
213
|
+
|
|
214
|
+
const bundlerContext = await this.getBuildContext(context, { outputPath });
|
|
215
|
+
const transformers: WebpackConfigTransformer[] = compact([
|
|
216
|
+
(configMutator) => configMutator.merge(ssrBuildConfig({ outputPath: join(outputPath, this.ssrDir) })),
|
|
217
|
+
replaceTerserPlugin({ prerender: !!this.prerender }),
|
|
218
|
+
...this.transformers,
|
|
219
|
+
]);
|
|
220
|
+
|
|
221
|
+
const reactEnv = context.env as ReactEnv;
|
|
222
|
+
const bundler: Bundler = await reactEnv.getBundler(bundlerContext, transformers);
|
|
223
|
+
return bundler;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private async getBuildContext(context: AppBuildContext, { outputPath }: { outputPath: string }) {
|
|
227
|
+
const { capsule } = context;
|
|
228
|
+
const reactEnv = context.env as ReactEnv;
|
|
179
229
|
const { distDir } = reactEnv.getCompiler();
|
|
180
|
-
const targetEntries =
|
|
230
|
+
const targetEntries = await this.getEntries(`${capsule.path}/${distDir}`);
|
|
181
231
|
const entries = targetEntries.map((entry) => require.resolve(`${capsule.path}/${distDir}/${basename(entry)}`));
|
|
182
|
-
const staticDir = join(outputPath, this.dir);
|
|
183
232
|
|
|
184
233
|
const bundlerContext: BundlerContext = Object.assign(context, {
|
|
185
234
|
targets: [
|
|
@@ -200,87 +249,16 @@ export class ReactApp implements Application {
|
|
|
200
249
|
},
|
|
201
250
|
});
|
|
202
251
|
|
|
203
|
-
|
|
204
|
-
const config = configMutator.addTopLevel('output', {
|
|
205
|
-
path: staticDir,
|
|
206
|
-
publicPath: `/`,
|
|
207
|
-
filename: '[name].[chunkhash].js',
|
|
208
|
-
});
|
|
209
|
-
if (this.prerender) config.addPlugin(prerenderPlugin(this.prerender));
|
|
210
|
-
if (config.raw.optimization?.minimizer) {
|
|
211
|
-
remove(config.raw.optimization?.minimizer, (minimizer) => {
|
|
212
|
-
return minimizer.constructor.name === 'TerserPlugin';
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
config.raw.optimization?.minimizer.push(this.getESBuildConfig());
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return config;
|
|
219
|
-
};
|
|
220
|
-
const transformers = [defaultTransformer, ...this.transformers];
|
|
221
|
-
const bundler: Bundler = await reactEnv.getBundler(bundlerContext, transformers);
|
|
222
|
-
return bundler;
|
|
252
|
+
return bundlerContext;
|
|
223
253
|
}
|
|
224
|
-
private getESBuildConfig = (isPrerendering = this.prerender) => {
|
|
225
|
-
// We don't want to use esbuild in case of prerendering since the headless browser puppeteer doesn't support
|
|
226
|
-
// the output of esbuild
|
|
227
|
-
|
|
228
|
-
if (isPrerendering) {
|
|
229
|
-
return new TerserPlugin({
|
|
230
|
-
extractComments: false,
|
|
231
|
-
terserOptions: {
|
|
232
|
-
parse: {
|
|
233
|
-
// We want terser to parse ecma 8 code. However, we don't want it
|
|
234
|
-
// to apply any minification steps that turns valid ecma 5 code
|
|
235
|
-
// into invalid ecma 5 code. This is why the 'compress' and 'output'
|
|
236
|
-
// sections only apply transformations that are ecma 5 safe
|
|
237
|
-
// https://github.com/facebook/create-react-app/pull/4234
|
|
238
|
-
ecma: 8,
|
|
239
|
-
},
|
|
240
|
-
compress: {
|
|
241
|
-
ecma: 5,
|
|
242
|
-
warnings: false,
|
|
243
|
-
// Disabled because of an issue with Uglify breaking seemingly valid code:
|
|
244
|
-
// https://github.com/facebook/create-react-app/issues/2376
|
|
245
|
-
// Pending further investigation:
|
|
246
|
-
// https://github.com/mishoo/UglifyJS2/issues/2011
|
|
247
|
-
comparisons: false,
|
|
248
|
-
// Disabled because of an issue with Terser breaking valid code:
|
|
249
|
-
// https://github.com/facebook/create-react-app/issues/5250
|
|
250
|
-
// Pending further investigation:
|
|
251
|
-
// https://github.com/terser-js/terser/issues/120
|
|
252
|
-
inline: 2,
|
|
253
|
-
},
|
|
254
|
-
mangle: {
|
|
255
|
-
safari10: true,
|
|
256
|
-
},
|
|
257
|
-
output: {
|
|
258
|
-
ecma: 5,
|
|
259
|
-
comments: false,
|
|
260
|
-
// Turned on because emoji and regex is not minified properly using default
|
|
261
|
-
// https://github.com/facebook/create-react-app/issues/2488
|
|
262
|
-
ascii_only: true,
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
return new TerserPlugin({
|
|
268
|
-
minify: TerserPlugin.esbuildMinify,
|
|
269
|
-
// `terserOptions` options will be passed to `esbuild`
|
|
270
|
-
// Link to options - https://esbuild.github.io/api/#minify
|
|
271
|
-
terserOptions: {
|
|
272
|
-
minify: true,
|
|
273
|
-
},
|
|
274
|
-
});
|
|
275
|
-
};
|
|
276
254
|
|
|
277
255
|
private getPublicDir(artifactsDir: string) {
|
|
278
256
|
return join(artifactsDir, this.applicationType, this.name);
|
|
279
257
|
}
|
|
280
258
|
|
|
281
|
-
async getEntries(): Promise<string[]> {
|
|
259
|
+
async getEntries(path?: string): Promise<string[]> {
|
|
282
260
|
if (Array.isArray(this.entry)) return this.entry;
|
|
283
|
-
return this.entry();
|
|
261
|
+
return this.entry(path);
|
|
284
262
|
}
|
|
285
263
|
|
|
286
264
|
async getSsrEntries(): Promise<string[]> {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { WebpackConfigMutator } from '@teambit/webpack';
|
|
2
|
+
import { remove } from 'lodash';
|
|
3
|
+
import TerserPlugin from 'terser-webpack-plugin';
|
|
2
4
|
|
|
3
5
|
export function addDevServer(configMutator: WebpackConfigMutator) {
|
|
4
6
|
return configMutator.addTopLevel('devServer', {
|
|
@@ -19,3 +21,69 @@ export function setOutput(configMutator: WebpackConfigMutator) {
|
|
|
19
21
|
|
|
20
22
|
return configMutator;
|
|
21
23
|
}
|
|
24
|
+
|
|
25
|
+
export function replaceTerserPlugin({ prerender = false }: { prerender: boolean }) {
|
|
26
|
+
return (configMutator: WebpackConfigMutator) => {
|
|
27
|
+
if (!configMutator.raw.optimization?.minimizer) return configMutator;
|
|
28
|
+
|
|
29
|
+
remove(configMutator.raw.optimization?.minimizer, (minimizer) => {
|
|
30
|
+
return minimizer.constructor.name === 'TerserPlugin';
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const terserer = prerender ? CreateTerserPluginForPrerender() : CreateTerserPlugin();
|
|
34
|
+
configMutator.raw.optimization?.minimizer.push(terserer);
|
|
35
|
+
|
|
36
|
+
return configMutator;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function CreateTerserPlugin() {
|
|
41
|
+
return new TerserPlugin({
|
|
42
|
+
minify: TerserPlugin.esbuildMinify,
|
|
43
|
+
// `terserOptions` options will be passed to `esbuild`
|
|
44
|
+
// Link to options - https://esbuild.github.io/api/#minify
|
|
45
|
+
terserOptions: {
|
|
46
|
+
minify: true,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function CreateTerserPluginForPrerender() {
|
|
52
|
+
return new TerserPlugin({
|
|
53
|
+
extractComments: false,
|
|
54
|
+
terserOptions: {
|
|
55
|
+
parse: {
|
|
56
|
+
// We want terser to parse ecma 8 code. However, we don't want it
|
|
57
|
+
// to apply any minification steps that turns valid ecma 5 code
|
|
58
|
+
// into invalid ecma 5 code. This is why the 'compress' and 'output'
|
|
59
|
+
// sections only apply transformations that are ecma 5 safe
|
|
60
|
+
// https://github.com/facebook/create-react-app/pull/4234
|
|
61
|
+
ecma: 8,
|
|
62
|
+
},
|
|
63
|
+
compress: {
|
|
64
|
+
ecma: 5,
|
|
65
|
+
warnings: false,
|
|
66
|
+
// Disabled because of an issue with Uglify breaking seemingly valid code:
|
|
67
|
+
// https://github.com/facebook/create-react-app/issues/2376
|
|
68
|
+
// Pending further investigation:
|
|
69
|
+
// https://github.com/mishoo/UglifyJS2/issues/2011
|
|
70
|
+
comparisons: false,
|
|
71
|
+
// Disabled because of an issue with Terser breaking valid code:
|
|
72
|
+
// https://github.com/facebook/create-react-app/issues/5250
|
|
73
|
+
// Pending further investigation:
|
|
74
|
+
// https://github.com/terser-js/terser/issues/120
|
|
75
|
+
inline: 2,
|
|
76
|
+
},
|
|
77
|
+
mangle: {
|
|
78
|
+
safari10: true,
|
|
79
|
+
},
|
|
80
|
+
output: {
|
|
81
|
+
ecma: 5,
|
|
82
|
+
comments: false,
|
|
83
|
+
// Turned on because emoji and regex is not minified properly using default
|
|
84
|
+
// https://github.com/facebook/create-react-app/issues/2488
|
|
85
|
+
ascii_only: true,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
@@ -35,3 +35,27 @@ export function ssrConfig(): Configuration {
|
|
|
35
35
|
},
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
export function buildConfig({ outputPath }: { outputPath: string }): Configuration {
|
|
40
|
+
return {
|
|
41
|
+
output: {
|
|
42
|
+
path: outputPath,
|
|
43
|
+
publicPath: `/`,
|
|
44
|
+
filename: '[name].[chunkhash].js',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function ssrBuildConfig({ outputPath }: { outputPath: string }): Configuration {
|
|
50
|
+
return {
|
|
51
|
+
target: 'node',
|
|
52
|
+
devtool: 'eval-cheap-source-map',
|
|
53
|
+
|
|
54
|
+
output: {
|
|
55
|
+
path: outputPath,
|
|
56
|
+
publicPath: `/`,
|
|
57
|
+
libraryTarget: 'commonjs',
|
|
58
|
+
filename: 'index.js',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<testsuites>
|
|
3
|
-
<testsuite name="teambit.react/react@0.0.
|
|
4
|
-
<testcase classname="index-file.spec.js" name="should match snapshot" time="0.
|
|
3
|
+
<testsuite name="teambit.react/react@0.0.807" timestamp="2022-08-04T03:53:03.273Z" tests="1" failures="0" errors="0" skipped="0">
|
|
4
|
+
<testcase classname="index-file.spec.js" name="should match snapshot" time="0.184"/>
|
|
5
5
|
</testsuite>
|
|
6
6
|
</testsuites>
|