@webiny/build-tools 6.3.0 → 6.4.0-beta.1

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.
@@ -1,4 +1,3 @@
1
- import { createRsbuild } from "@rsbuild/core";
2
1
  import { createRsbuildConfig } from "./createRsbuildConfig.js";
3
2
  import { printBuildStats } from "../printBuildStats.js";
4
3
 
@@ -7,6 +6,8 @@ export const createBuildAdmin =
7
6
  async ({ cwd }) => {
8
7
  process.env.NODE_ENV = "production";
9
8
 
9
+ // Must be a dynamic import — see rslibCompile.js for the reason.
10
+ const { createRsbuild } = await import("@rsbuild/core");
10
11
  const rsbuildConfig = createRsbuildConfig({ cwd });
11
12
 
12
13
  const rsbuild = await createRsbuild({ rsbuildConfig });
@@ -19,12 +19,6 @@ export const createRsbuildConfig = ({ cwd }) => {
19
19
  },
20
20
  define: envVars
21
21
  },
22
- resolve: {
23
- alias: {
24
- // This is a temporary fix, until we sort out the `react-butterfiles` dependency.
25
- "react-butterfiles": "@webiny/app/react-butterfiles"
26
- }
27
- },
28
22
  output: { distPath: { root: paths.admin.outputFolder } },
29
23
  mode,
30
24
  dev: { hmr: true },
@@ -51,7 +45,7 @@ export const createRsbuildConfig = ({ cwd }) => {
51
45
  }
52
46
  }
53
47
  },
54
- server: { port: process.env.PORT || 3001 },
48
+ server: { port: process.env.PORT || 3001, host: "0.0.0.0" },
55
49
  html: {
56
50
  template: paths.projectRootFolder + "/public/index.html"
57
51
  },
@@ -1,4 +1,3 @@
1
- import { createRsbuild } from "@rsbuild/core";
2
1
  import { createRsbuildConfig } from "./createRsbuildConfig.js";
3
2
 
4
3
  export const createWatchAdmin =
@@ -6,6 +5,8 @@ export const createWatchAdmin =
6
5
  async ({ cwd }) => {
7
6
  process.env.NODE_ENV = "development";
8
7
 
8
+ // Must be a dynamic import — see rslibCompile.js for the reason.
9
+ const { createRsbuild } = await import("@rsbuild/core");
9
10
  const rsbuildConfig = createRsbuildConfig({ cwd });
10
11
 
11
12
  const rsbuild = await createRsbuild({ rsbuildConfig });
@@ -1,4 +1,3 @@
1
- import { createRsbuild } from "@rsbuild/core";
2
1
  import { createRsbuildConfig } from "./createRsbuildConfig.js";
3
2
  import { printBuildStats } from "../printBuildStats.js";
4
3
 
@@ -7,7 +6,9 @@ export const createBuildFunction =
7
6
  async ({ cwd }) => {
8
7
  process.env.NODE_ENV = "production";
9
8
 
10
- const rsbuildConfig = createRsbuildConfig({ cwd });
9
+ // Must be a dynamic import — see rslibCompile.js for the reason.
10
+ const { createRsbuild } = await import("@rsbuild/core");
11
+ const rsbuildConfig = await createRsbuildConfig({ cwd });
11
12
 
12
13
  const rsbuild = await createRsbuild({ rsbuildConfig });
13
14
 
@@ -1,19 +1,25 @@
1
1
  import path from "path";
2
- import rspack from "@rspack/core";
3
2
  import { pluginTypeCheck } from "@rsbuild/plugin-type-check";
4
3
  import { createImportValidatorPlugin } from "../importValidatorPlugin.js";
5
4
 
6
- export const createRsbuildConfig = ({ cwd }) => {
5
+ export const createRsbuildConfig = async ({ cwd }) => {
6
+ // Must be a dynamic import — see rslibCompile.js for the reason.
7
+ const { default: rspack } = await import("@rspack/core");
7
8
  const paths = getPaths(cwd);
8
9
  const mode = getMode();
10
+ const isDebugEnabled = process.env.DEBUG === "true";
11
+
12
+ // Configurable via WEBINY_API_MAX_BUNDLE_SIZE (MB), default 10 MB.
13
+ const maxBundleSize = (parseFloat(process.env.WEBINY_API_MAX_BUNDLE_SIZE) || 10) * 1024 * 1024;
9
14
 
10
15
  return /** @type {import("@rsbuild/core").RsbuildConfig} */ ({
11
16
  source: { entry: { index: paths.fn.entryFile } },
12
17
  output: {
13
18
  module: true,
14
19
  target: "node",
20
+ minify: true,
15
21
  sourceMap: {
16
- js: process.env.DEBUG === "true" ? "source-map" : false
22
+ js: isDebugEnabled ? "source-map" : false
17
23
  },
18
24
  filename: {
19
25
  js: pathData => {
@@ -26,7 +32,10 @@ export const createRsbuildConfig = ({ cwd }) => {
26
32
  distPath: { root: paths.fn.outputFolder }
27
33
  },
28
34
  performance: {
29
- printFileSize: false
35
+ printFileSize: false,
36
+ hints: "error",
37
+ maxEntrypointSize: maxBundleSize,
38
+ maxAssetSize: maxBundleSize
30
39
  },
31
40
  tools: {
32
41
  rspack: {
@@ -1,4 +1,3 @@
1
- import { createRsbuild } from "@rsbuild/core";
2
1
  import { createRsbuildConfig } from "./createRsbuildConfig.js";
3
2
 
4
3
  export const createWatchFunction =
@@ -6,7 +5,9 @@ export const createWatchFunction =
6
5
  async ({ cwd }) => {
7
6
  process.env.NODE_ENV = "development";
8
7
 
9
- const rsbuildConfig = createRsbuildConfig({ cwd });
8
+ // Must be a dynamic import — see rslibCompile.js for the reason.
9
+ const { createRsbuild } = await import("@rsbuild/core");
10
+ const rsbuildConfig = await createRsbuildConfig({ cwd });
10
11
 
11
12
  const rsbuild = await createRsbuild({ rsbuildConfig });
12
13
 
package/index.d.ts CHANGED
@@ -5,10 +5,6 @@ export { RspackConfig };
5
5
  // Build commands.
6
6
  export type BuildCommand<TOptions = Record<string, any>> = (options: TOptions) => Promise<void>;
7
7
 
8
- export interface BabelConfig {
9
- [key: string]: any;
10
- }
11
-
12
8
  export interface SwcConfig {
13
9
  [key: string]: any;
14
10
  }
@@ -20,7 +16,6 @@ export interface DefinePluginOptions {
20
16
  export interface BuildAppConfigOverrides {
21
17
  entry?: string;
22
18
  openBrowser?: boolean;
23
- babel?: (config: BabelConfig) => BabelConfig;
24
19
  }
25
20
  // Build commands - apps.
26
21
  export interface BuildAppConfig {
@@ -51,7 +46,6 @@ interface BuildFunctionConfig {
51
46
  };
52
47
  define?: DefinePluginOptions;
53
48
  rspack?: (config: RspackConfig) => RspackConfig;
54
- babel?: (config: BabelConfig) => BabelConfig;
55
49
  swc?: (config: SwcConfig) => SwcConfig;
56
50
  };
57
51
  }
@@ -71,12 +65,5 @@ interface BuildPackageConfig {
71
65
  };
72
66
  }
73
67
 
74
- interface BabelConfigParams {
75
- path: string;
76
- esm?: boolean;
77
- }
78
-
79
68
  export function createBuildPackage(options: BuildPackageConfig): BuildCommand;
80
69
  export function createWatchPackage(options: BuildPackageConfig): BuildCommand;
81
- export function createBabelConfigForNode(options: BabelConfigParams): BabelConfig;
82
- export function createBabelConfigForReact(options: BabelConfigParams): BabelConfig;
package/index.js CHANGED
@@ -1,8 +1,3 @@
1
1
  export { createWatchAdmin, createBuildAdmin } from "./bundling/admin/index.js";
2
2
  export { createBuildFunction, createWatchFunction } from "./bundling/function/index.js";
3
- export {
4
- createWatchPackage,
5
- createBuildPackage,
6
- createBabelConfigForNode,
7
- createBabelConfigForReact
8
- } from "./packages/index.js";
3
+ export { createWatchPackage, createBuildPackage } from "./packages/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/build-tools",
3
- "version": "6.3.0",
3
+ "version": "6.4.0-beta.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -17,27 +17,20 @@
17
17
  "Adrian Smijulj <adrian@webiny.com>"
18
18
  ],
19
19
  "dependencies": {
20
- "@babel/core": "7.29.0",
21
- "@babel/preset-env": "7.29.3",
22
- "@babel/preset-react": "7.28.5",
23
- "@babel/preset-typescript": "7.28.5",
24
- "@babel/runtime": "7.29.2",
25
- "@rsbuild/core": "1.7.5",
26
- "@rsbuild/plugin-react": "1.4.6",
20
+ "@rsbuild/core": "2.0.6",
21
+ "@rsbuild/plugin-react": "2.0.0",
27
22
  "@rsbuild/plugin-sass": "1.5.2",
28
- "@rsbuild/plugin-svgr": "1.3.1",
23
+ "@rsbuild/plugin-svgr": "2.0.2",
29
24
  "@rsbuild/plugin-type-check": "1.3.4",
30
- "@rspack/core": "1.7.11",
31
- "@svgr/webpack": "8.1.0",
25
+ "@rslib/core": "0.21.5",
26
+ "@rspack/core": "2.0.3",
32
27
  "@swc/plugin-emotion": "14.9.0",
33
- "@tailwindcss/postcss": "4.2.4",
34
- "@types/webpack-env": "1.18.8",
28
+ "@tailwindcss/postcss": "4.3.0",
35
29
  "chalk": "5.6.2",
36
- "chokidar": "5.0.0",
37
30
  "css-loader": "7.1.4",
38
31
  "fast-glob": "3.3.3",
39
32
  "find-up": "8.0.0",
40
- "fs-extra": "11.3.4",
33
+ "fs-extra": "11.3.5",
41
34
  "get-yarn-workspaces": "1.0.2",
42
35
  "load-json-file": "7.0.1",
43
36
  "lodash": "4.18.1",
@@ -47,7 +40,7 @@
47
40
  "react-refresh": "0.18.0",
48
41
  "rimraf": "6.1.3",
49
42
  "sass": "1.99.0",
50
- "sass-loader": "16.0.7",
43
+ "sass-loader": "16.0.8",
51
44
  "style-loader": "4.0.0",
52
45
  "ts-morph": "28.0.0",
53
46
  "tsx": "4.21.0",
@@ -64,12 +57,7 @@
64
57
  "!!raw-loader!"
65
58
  ],
66
59
  "dependencies": [
67
- "@babel/preset-react",
68
- "@svgr/webpack",
69
- "@babel/preset-env",
70
- "@babel/preset-typescript",
71
60
  "@swc/plugin-emotion",
72
- "@types/webpack-env",
73
61
  "postcss-loader",
74
62
  "raw-loader",
75
63
  "react-refresh",
@@ -88,5 +76,5 @@
88
76
  "access": "public",
89
77
  "directory": "."
90
78
  },
91
- "gitHead": "7cefe15431dbd65504e1f58147dc9e55bcbfa693"
79
+ "gitHead": "73237b8243693038c072bae1c0b783387448cbbe"
92
80
  }
@@ -1,9 +1,9 @@
1
1
  import fs from "fs";
2
2
  import { join } from "path";
3
3
 
4
- export const copyToDist = (path, { cwd, logs }) => {
4
+ export const copyToDist = (path, { cwd, logs, outputDir }) => {
5
5
  const from = join(cwd, path);
6
- const to = join(cwd, "dist", path);
6
+ const to = join(outputDir || join(cwd, "dist"), path);
7
7
  if (fs.existsSync(from)) {
8
8
  fs.copyFileSync(from, to);
9
9
  logs !== false && console.log(`Copied ${path}.`);
@@ -0,0 +1,63 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import { dirname } from "path";
4
+ import glob from "fast-glob";
5
+
6
+ const COMPILE_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx"];
7
+ const SKIP_EXTENSIONS = [".d.ts"];
8
+
9
+ export const rslibCompile = async ({ cwd }) => {
10
+ // Copy non-compilable files (assets, json, graphql, etc.) as-is.
11
+ const pattern = path.join(cwd, "src/**/*.*").replace(/\\/g, "/");
12
+ const allFiles = glob.sync(pattern, { onlyFiles: true, dot: true });
13
+
14
+ for (const file of allFiles) {
15
+ const shouldCompile = COMPILE_EXTENSIONS.some(ext => file.endsWith(ext));
16
+ const shouldSkip = SKIP_EXTENSIONS.some(ext => file.endsWith(ext));
17
+
18
+ if (!shouldCompile || shouldSkip) {
19
+ const destPath = file.replace(path.join(cwd, "src"), path.join(cwd, "dist"));
20
+ fs.mkdirSync(dirname(destPath), { recursive: true });
21
+ fs.copyFileSync(file, destPath);
22
+ }
23
+ }
24
+
25
+ // Must be a dynamic import. @rslib/core statically loads rspack's native
26
+ // binding. Workers that also run createBuildAdmin load a different rspack
27
+ // version via rsbuild, so two native binaries end up in the same process
28
+ // and cause a SIGSEGV. Deferring the import keeps each rspack isolated to
29
+ // the workers that actually need it.
30
+ const [{ createRslib }, { pluginSvgr }] = await Promise.all([
31
+ import("@rslib/core"),
32
+ import("@rsbuild/plugin-svgr")
33
+ ]);
34
+
35
+ const rslib = await createRslib({
36
+ cwd,
37
+ config: {
38
+ lib: [{ format: "esm", bundle: false }],
39
+ source: {
40
+ // SVGs included so rslib runs them through pluginSvgr and emits
41
+ // a .js React-component module alongside the copied .svg asset.
42
+ entry: ["./src/**/*.{ts,tsx,js,jsx,svg}"],
43
+ alias: { "~": "./src" }
44
+ },
45
+ output: {
46
+ target: "web",
47
+ distPath: { root: "./dist" },
48
+ cleanDistPath: false,
49
+ sourceMap: { js: "source-map" },
50
+ // mixedImport emits each SVG as a static asset for the default URL
51
+ // export. Without a hash, two files named the same (e.g. fullscreen.svg
52
+ // in different dirs) collide at static/svg/fullscreen.svg.
53
+ // loader-utils [ext] has no leading dot, so "[name].[hash][ext]" produces
54
+ // "foo.hashsvg". Use an explicit ".svg" suffix instead.
55
+ filename: { svg: "[name].[contenthash:8].svg" }
56
+ },
57
+ plugins: [pluginSvgr({ mixedImport: true, svgrOptions: { exportType: "named" } })]
58
+ }
59
+ });
60
+
61
+ const { close } = await rslib.build();
62
+ await close();
63
+ };
@@ -3,7 +3,7 @@ import ts from "typescript";
3
3
  import merge from "lodash/merge.js";
4
4
  import { replaceTscAliases } from "./tsAliasReplacer.js";
5
5
 
6
- export const tsCompile = async ({ cwd = "", overrides, debug }) => {
6
+ export const tsCompile = async ({ cwd = "", overrides, debug, outputDir, checkOnly = false }) => {
7
7
  // Normalize path separators to forward slashes for consistent behavior on Windows.
8
8
  const normalizedCwd = cwd.replace(/\\/g, "/");
9
9
 
@@ -23,12 +23,22 @@ export const tsCompile = async ({ cwd = "", overrides, debug }) => {
23
23
  console.log(readTsConfig);
24
24
  }
25
25
  }
26
+ if (outputDir) {
27
+ readTsConfig.compilerOptions = readTsConfig.compilerOptions || {};
28
+ readTsConfig.compilerOptions.outDir = outputDir;
29
+ readTsConfig.compilerOptions.declarationDir = outputDir;
30
+ }
31
+
26
32
  const parsedJsonConfigFile = ts.parseJsonConfigFileContent(readTsConfig, ts.sys, normalizedCwd);
27
33
 
28
34
  const { projectReferences, options, fileNames, errors } = parsedJsonConfigFile;
29
35
 
30
36
  const filteredFileNames = fileNames.filter(fileName => !fileName.endsWith(".d.ts"));
31
37
 
38
+ if (checkOnly) {
39
+ options.noEmit = true;
40
+ }
41
+
32
42
  const program = ts.createProgram({
33
43
  projectReferences,
34
44
  options,
@@ -36,6 +46,23 @@ export const tsCompile = async ({ cwd = "", overrides, debug }) => {
36
46
  configFileParsingDiagnostics: errors
37
47
  });
38
48
 
49
+ if (checkOnly) {
50
+ const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(errors);
51
+
52
+ if (allDiagnostics.length) {
53
+ const formatHost = {
54
+ getCanonicalFileName: path => path,
55
+ getCurrentDirectory: () => normalizedCwd,
56
+ getNewLine: () => ts.sys.newLine
57
+ };
58
+ const message = ts.formatDiagnostics(allDiagnostics, formatHost);
59
+ if (message) {
60
+ throw { message };
61
+ }
62
+ }
63
+ return;
64
+ }
65
+
39
66
  const { diagnostics, emitSkipped } = program.emit(
40
67
  undefined, // targetSourceFile
41
68
  (fileName, data, writeByteOrderMark) => {
@@ -67,7 +94,6 @@ export const tsCompile = async ({ cwd = "", overrides, debug }) => {
67
94
  throw { message: "TypeScript compilation failed." };
68
95
  }
69
96
 
70
- // Resolve ~ path aliases in .d.ts files
71
- const distDir = options.outDir || join(normalizedCwd, "dist");
97
+ const distDir = outputDir || options.outDir || join(normalizedCwd, "dist");
72
98
  await replaceTscAliases({ distDir, cwd: normalizedCwd, debug });
73
99
  };
@@ -1,7 +1,7 @@
1
1
  import * as rimraf from "rimraf";
2
2
  import { join } from "path";
3
3
  import fs from "node:fs";
4
- import { babelCompile } from "./buildPackage/babelCompile.js";
4
+ import { rslibCompile } from "./buildPackage/rslibCompile.js";
5
5
  import { tsCompile } from "./buildPackage/tsCompile.js";
6
6
  import { copyToDist } from "./buildPackage/copyToDist.js";
7
7
  import { validateEsmImports } from "./buildPackage/validateEsmImports.js";
@@ -26,25 +26,68 @@ export default async options => {
26
26
  // Validate ESM imports before compiling
27
27
  await validateEsmImports({ cwd, logs: options.logs });
28
28
 
29
+ const distDir = join(cwd, "dist");
30
+
31
+ if (options.safeReplace) {
32
+ await buildWithSafeReplace(options, distDir);
33
+ } else {
34
+ await buildDirect(options, distDir);
35
+ }
36
+
37
+ const duration = (new Date() - start) / 1000;
38
+ options.logs !== false && console.log(`Done! Build finished in ${duration + "s"}.`);
39
+
40
+ return { duration };
41
+ };
42
+
43
+ async function buildDirect(options, distDir) {
29
44
  // Clear dist/ contents without removing the directory itself.
30
45
  // node_modules/@webiny/<pkg> symlinks directly to dist/, so deleting
31
46
  // the directory would leave a dangling symlink and break Rspack resolution.
32
- const distDir = join(cwd, "dist");
33
47
  if (fs.existsSync(distDir)) {
34
48
  for (const entry of fs.readdirSync(distDir)) {
35
49
  fs.rmSync(join(distDir, entry), { recursive: true, force: true });
36
50
  }
37
51
  }
38
52
 
39
- await babelCompile(options);
53
+ await rslibCompile(options);
40
54
  await tsCompile(options);
41
55
 
42
56
  options.logs !== false && console.log("Copying meta files...");
43
57
  copyToDist("package.json", options);
44
58
  copyToDist("LICENSE", options);
59
+ }
45
60
 
46
- const duration = (new Date() - start) / 1000;
47
- options.logs !== false && console.log(`Done! Build finished in ${duration + "s"}.`);
61
+ async function buildWithSafeReplace(options, distDir) {
62
+ const stagingDir = distDir + "._build";
48
63
 
49
- return { duration };
50
- };
64
+ // Clean up any leftover staging dir from a previous failed build.
65
+ if (fs.existsSync(stagingDir)) {
66
+ fs.rmSync(stagingDir, { recursive: true, force: true });
67
+ }
68
+ fs.mkdirSync(stagingDir, { recursive: true });
69
+
70
+ const stagingOptions = { ...options, outputDir: stagingDir };
71
+
72
+ await babelCompile(stagingOptions);
73
+ await tsCompile(stagingOptions);
74
+
75
+ stagingOptions.logs !== false && console.log("Copying meta files...");
76
+ copyToDist("package.json", stagingOptions);
77
+ copyToDist("LICENSE", stagingOptions);
78
+
79
+ // Fast-swap: clear dist contents and move staged files in.
80
+ if (fs.existsSync(distDir)) {
81
+ for (const entry of fs.readdirSync(distDir)) {
82
+ fs.rmSync(join(distDir, entry), { recursive: true, force: true });
83
+ }
84
+ } else {
85
+ fs.mkdirSync(distDir, { recursive: true });
86
+ }
87
+
88
+ for (const entry of fs.readdirSync(stagingDir)) {
89
+ fs.renameSync(join(stagingDir, entry), join(distDir, entry));
90
+ }
91
+
92
+ fs.rmSync(stagingDir, { recursive: true, force: true });
93
+ }
package/packages/index.js CHANGED
@@ -2,5 +2,3 @@ export { default as watchPackage } from "./watchPackage.js";
2
2
  export { default as createWatchPackage } from "./createWatchPackage.js";
3
3
  export { default as buildPackage } from "./buildPackage.js";
4
4
  export { default as createBuildPackage } from "./createBuildPackage.js";
5
- export { default as createBabelConfigForNode } from "./createBabelConfigForNode.js";
6
- export { default as createBabelConfigForReact } from "./createBabelConfigForReact.js";
@@ -1,117 +1,29 @@
1
- import path from "path";
2
- import fs from "fs/promises";
3
- import { transformFileAsync } from "@babel/core";
4
- import chokidar from "chokidar";
5
- import baseFs from "node:fs";
6
-
7
- let compilationQueue = [];
8
- let debounceTimer = null;
9
- const DEBOUNCE_DELAY = 1000; // 1 second
10
-
11
- const flushCompilationQueue = () => {
12
- if (compilationQueue.length > 0) {
13
- if (compilationQueue.length === 1) {
14
- console.log(`Successfully compiled ${compilationQueue[0]}.`);
15
- } else {
16
- console.log(`Successfully compiled ${compilationQueue.length} files.`);
17
- }
18
- compilationQueue = [];
19
- }
20
- };
21
-
22
- const logCompilation = inputPathRelative => {
23
- compilationQueue.push(inputPathRelative);
24
-
25
- clearTimeout(debounceTimer);
26
- debounceTimer = setTimeout(() => {
27
- flushCompilationQueue();
28
- }, DEBOUNCE_DELAY);
29
- };
30
-
31
- const getBabelFile = cwd => {
32
- const babelJs = path.join(cwd, ".babelrc.js");
33
- const babelCjs = path.join(cwd, ".babelrc.cjs");
34
-
35
- if (baseFs.existsSync(babelJs)) {
36
- return babelJs;
37
- } else if (baseFs.existsSync(babelCjs)) {
38
- return babelCjs;
39
- }
40
- throw new Error("No Babel configuration file found (.babelrc.js or .babelrc.cjs).");
41
- };
42
-
43
- const compileFile = async (cwd, inputPath, outputPath) => {
44
- const inputPathRelative = path.relative(cwd, inputPath);
45
-
46
- const configFile = getBabelFile(cwd);
47
-
48
- const result = await transformFileAsync(inputPath, {
49
- configFile: configFile,
50
- sourceMaps: true
51
- });
52
-
53
- if (!result || !result.code) {
54
- throw new Error(`Failed to compile: ${inputPath}`);
55
- }
56
-
57
- // Write compiled file
58
- await fs.mkdir(path.dirname(outputPath), { recursive: true });
59
- await fs.writeFile(outputPath, result.code);
60
-
61
- // Write source map
62
- if (result.map) {
63
- await fs.writeFile(`${outputPath}.map`, JSON.stringify(result.map));
64
- }
65
-
66
- logCompilation(inputPathRelative);
67
- };
68
-
69
- const srcToDist = filePath =>
70
- path.join(
71
- filePath
72
- .replace(`${path.sep}src${path.sep}`, `${path.sep}dist${path.sep}`)
73
- .replace(/\.(ts|tsx)$/, ".js")
74
- );
75
-
76
1
  export default async options => {
77
- const srcDir = path.join(options.cwd, "src");
78
-
79
- // Watch the src directory recursively for new files
80
- const watcher = chokidar.watch(srcDir, {
81
- ignored: /(^|[\/\\])\../, // ignore dotfiles
82
- persistent: true,
83
- ignoreInitial: false
84
- });
85
-
86
- const isTsFile = filePath => /\.(ts|tsx)$/.test(filePath);
87
-
88
- watcher.on("add", async srcPath => {
89
- if (!isTsFile(srcPath)) {
90
- return;
91
- }
92
-
93
- const distPath = srcToDist(srcPath);
94
-
95
- try {
96
- await compileFile(options.cwd, srcPath, distPath);
97
- } catch (err) {
98
- console.error("Error compiling:", err);
99
- }
100
- });
101
-
102
- watcher.on("change", async srcPath => {
103
- if (!isTsFile(srcPath)) {
104
- return;
105
- }
106
-
107
- const distPath = srcToDist(srcPath);
108
-
109
- try {
110
- await compileFile(options.cwd, srcPath, distPath);
111
- } catch (err) {
112
- console.error("Error compiling:", err);
2
+ const { cwd } = options;
3
+
4
+ // Must be a dynamic import — see rslibCompile.js for the reason.
5
+ const [{ createRslib }, { pluginSvgr }] = await Promise.all([
6
+ import("@rslib/core"),
7
+ import("@rsbuild/plugin-svgr")
8
+ ]);
9
+
10
+ const rslib = await createRslib({
11
+ cwd,
12
+ config: {
13
+ lib: [{ format: "esm", bundle: false }],
14
+ source: {
15
+ entry: ["./src/**/*.{ts,tsx,js,jsx}"],
16
+ alias: { "~": "./src" }
17
+ },
18
+ output: {
19
+ target: "web",
20
+ distPath: { root: "./dist" },
21
+ cleanDistPath: false,
22
+ sourceMap: { js: "source-map" }
23
+ },
24
+ plugins: [pluginSvgr({ mixedImport: true, svgrOptions: { exportType: "named" } })]
113
25
  }
114
26
  });
115
27
 
116
- console.log("Watching for changes...");
28
+ await rslib.build({ watch: true });
117
29
  };
package/.babelrc.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require("./packages").createBabelConfigForNode({ path: __dirname });
@@ -1,103 +0,0 @@
1
- import fs from "fs";
2
- import { dirname, join, parse, relative } from "path";
3
- import * as babel from "@babel/core";
4
- import glob from "fast-glob";
5
-
6
- const BABEL_COMPILE_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx"];
7
- const BABEL_SKIP_EXTENSIONS = [".d.ts"];
8
-
9
- const withSourceMapUrl = (file, code) => {
10
- const { name } = parse(file);
11
- return [code, "", `//# sourceMappingURL=${name}.js.map`].join("\n");
12
- };
13
-
14
- const getDistCopyFilePath = ({ file, cwd }) => {
15
- const relativeDir = relative(cwd, file);
16
- return join(cwd, relativeDir.replace("src", "dist"));
17
- };
18
-
19
- const getDistFilePaths = ({ file, cwd }) => {
20
- const { dir, name } = parse(file);
21
-
22
- const relativeDir = relative(cwd, dir);
23
-
24
- const code = join(cwd, relativeDir.replace("src", "dist"), name + ".js");
25
- const map = join(cwd, relativeDir.replace("src", "dist"), name + ".js.map");
26
- return { code, map };
27
- };
28
-
29
- export const babelCompile = async ({ cwd }) => {
30
- // We're passing "*.*" just because we want to copy all files that cannot be compiled.
31
- // We want to have the same behaviour that the Babel CLI's "--copy-files" flag provides.
32
- const pattern = join(cwd, "src/**/*.*").replace(/\\/g, "/");
33
- const files = glob.sync(pattern, {
34
- onlyFiles: true,
35
- dot: true
36
- });
37
-
38
- const compilations = [];
39
- const copies = [];
40
-
41
- for (let i = 0; i < files.length; i++) {
42
- const file = files[i];
43
- if (
44
- fileEndsWith(file, BABEL_COMPILE_EXTENSIONS) &&
45
- !fileEndsWith(file, BABEL_SKIP_EXTENSIONS)
46
- ) {
47
- compilations.push(
48
- babel
49
- .transformFileAsync(file, {
50
- cwd,
51
- sourceMaps: true
52
- })
53
- .then(results => [file, results])
54
- );
55
- continue;
56
- }
57
-
58
- // All other files should be copied as-is.
59
- copies.push(copyFile(file, cwd));
60
- }
61
-
62
- // At this point, just wait for compilations to be completed, so we can proceed with writing the files ASAP.
63
- await Promise.all(compilations);
64
-
65
- const writes = [];
66
- for (let i = 0; i < compilations.length; i++) {
67
- const [file, result] = await compilations[i];
68
- const { code, map } = result;
69
-
70
- const paths = getDistFilePaths({ file, cwd });
71
- fs.mkdirSync(dirname(paths.code), { recursive: true });
72
-
73
- // Save the compiled JS file.
74
- writes.push(fs.promises.writeFile(paths.code, withSourceMapUrl(file, code), "utf8"));
75
-
76
- // Save source maps file.
77
- const mapJson = JSON.stringify(map);
78
- writes.push(fs.promises.writeFile(paths.map, mapJson, "utf8"));
79
- }
80
-
81
- // Wait until all files have been written to disk.
82
- return Promise.all([...writes, ...copies]);
83
- };
84
-
85
- function copyFile(file, cwd) {
86
- return new Promise((resolve, reject) => {
87
- try {
88
- const destPath = getDistCopyFilePath({ file, cwd });
89
- if (!fs.existsSync(dirname(destPath))) {
90
- fs.mkdirSync(dirname(destPath), { recursive: true });
91
- }
92
-
93
- fs.copyFileSync(file, destPath);
94
- resolve();
95
- } catch (e) {
96
- reject(e);
97
- }
98
- });
99
- }
100
-
101
- function fileEndsWith(file, extensions) {
102
- return extensions.some(ext => file.endsWith(ext));
103
- }
@@ -1,19 +0,0 @@
1
- export default ({ path }) => {
2
- return {
3
- presets: [
4
- ["@babel/preset-react", { useBuiltIns: true }],
5
- ["@babel/preset-typescript", { isTSX: true, allExtensions: true }]
6
- ],
7
- plugins: [
8
- [
9
- "babel-plugin-module-resolver",
10
- {
11
- cwd: path,
12
- alias: {
13
- "~": "./src"
14
- }
15
- }
16
- ]
17
- ]
18
- };
19
- };
@@ -1,20 +0,0 @@
1
- export default ({ path }) => ({
2
- presets: [
3
- ["@babel/preset-react", { useBuiltIns: true }],
4
- ["@babel/preset-typescript", { isTSX: true, allExtensions: true }]
5
- ],
6
- plugins: [
7
- "babel-plugin-macros",
8
- "@babel/plugin-proposal-throw-expressions",
9
- ["@emotion/babel-plugin", { autoLabel: "dev-only" }],
10
- [
11
- "babel-plugin-module-resolver",
12
- {
13
- cwd: path,
14
- alias: {
15
- "~": "./src"
16
- }
17
- }
18
- ]
19
- ]
20
- });
@@ -1,46 +0,0 @@
1
- import { loadJsonFileSync } from "load-json-file";
2
-
3
- export default ({ path, esm }) => {
4
- return {
5
- presets: [
6
- [
7
- "@babel/preset-env",
8
- {
9
- targets: {
10
- // nodejs - to easily find this with search. there is a lot of "node" in the code
11
- node: 24
12
- },
13
- modules: esm ? false : "auto",
14
- exclude: [
15
- "transform-typeof-symbol",
16
- "@babel/plugin-proposal-optional-chaining",
17
- "@babel/plugin-proposal-nullish-coalescing-operator",
18
- "@babel/plugin-transform-async-to-generator",
19
- "@babel/plugin-transform-regenerator",
20
- "@babel/plugin-proposal-dynamic-import"
21
- ]
22
- }
23
- ],
24
- "@babel/preset-typescript"
25
- ],
26
- plugins: [
27
- [
28
- "@babel/plugin-transform-runtime",
29
- {
30
- useESModules: !!esm,
31
- version: loadJsonFileSync(require.resolve("@babel/runtime/package.json"))
32
- .version
33
- }
34
- ],
35
- [
36
- "babel-plugin-module-resolver",
37
- {
38
- cwd: path,
39
- alias: {
40
- "~": "./src"
41
- }
42
- }
43
- ]
44
- ]
45
- };
46
- };