@webiny/build-tools 6.0.0-rc.7 → 6.1.0-beta.0

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.
@@ -33,11 +33,21 @@ export const createRsbuildConfig = ({ cwd }) => {
33
33
  },
34
34
  tools: {
35
35
  postcss: (_, { addPlugins }) => {
36
- addPlugins(
36
+ addPlugins([
37
+ createInjectTailwindSourcePlugin(
38
+ path.join(paths.projectRootFolder, "extensions")
39
+ ),
37
40
  tailwindcss({
38
41
  base: getTailwindBasePath(paths.projectRootFolder)
39
42
  })
40
- );
43
+ ]);
44
+ },
45
+ rspack: {
46
+ watchOptions: {
47
+ // Wait for dependency builds to finish before triggering a recompilation.
48
+ aggregateTimeout: 500,
49
+ ignored: ["**/node_modules/**", "**/.git/**"]
50
+ }
41
51
  }
42
52
  },
43
53
  server: { port: 3001 },
@@ -104,6 +114,17 @@ const getTailwindBasePath = projectRootFolderPath => {
104
114
  return path.join(projectRootFolderPath, "node_modules", "@webiny");
105
115
  };
106
116
 
117
+ /*
118
+ Injects an `@source` directive into the Tailwind CSS AST at build time, pointing to the
119
+ given absolute path. https://tailwindcss.com/docs/functions-and-directives#source-directive
120
+ */
121
+ const createInjectTailwindSourcePlugin = sourcePath => ({
122
+ postcssPlugin: "inject-tailwind-source",
123
+ Once(root) {
124
+ root.prepend(`@source "${sourcePath}";`);
125
+ }
126
+ });
127
+
107
128
  const getEnvVars = () => {
108
129
  const raw = Object.keys(process.env)
109
130
  .filter(key => {
@@ -30,7 +30,7 @@ export const createRsbuildConfig = ({ cwd }) => {
30
30
  },
31
31
  tools: {
32
32
  rspack: {
33
- externals: [/^@aws-sdk/, /^sharp$/],
33
+ externals: [/^@aws-sdk/, /^aws-sdk$/, /^sharp$/],
34
34
  plugins: [
35
35
  // This is necessary to enable JSDOM usage in Lambda.
36
36
  // https://rspack.dev/plugins/webpack/ignore-plugin
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/build-tools",
3
- "version": "6.0.0-rc.7",
3
+ "version": "6.1.0-beta.0",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "description": "A collection of utilities for Webiny project.",
@@ -15,26 +15,26 @@
15
15
  ],
16
16
  "dependencies": {
17
17
  "@babel/core": "7.29.0",
18
- "@babel/preset-env": "7.29.0",
18
+ "@babel/preset-env": "7.29.2",
19
19
  "@babel/preset-react": "7.28.5",
20
20
  "@babel/preset-typescript": "7.28.5",
21
- "@babel/runtime": "7.28.6",
22
- "@rsbuild/core": "1.7.3",
23
- "@rsbuild/plugin-react": "1.4.5",
24
- "@rsbuild/plugin-sass": "1.5.0",
25
- "@rsbuild/plugin-svgr": "1.3.0",
21
+ "@babel/runtime": "7.29.2",
22
+ "@rsbuild/core": "1.7.4",
23
+ "@rsbuild/plugin-react": "1.4.6",
24
+ "@rsbuild/plugin-sass": "1.5.1",
25
+ "@rsbuild/plugin-svgr": "1.3.1",
26
26
  "@rsbuild/plugin-type-check": "1.3.4",
27
- "@rspack/core": "1.7.8",
28
- "@svgr/webpack": "6.5.1",
29
- "@swc/plugin-emotion": "11.5.0",
30
- "@tailwindcss/postcss": "4.2.1",
27
+ "@rspack/core": "1.7.10",
28
+ "@svgr/webpack": "8.1.0",
29
+ "@swc/plugin-emotion": "14.7.0",
30
+ "@tailwindcss/postcss": "4.2.2",
31
31
  "@types/webpack-env": "1.18.8",
32
- "chalk": "4.1.2",
33
- "chokidar": "4.0.3",
32
+ "chalk": "5.6.2",
33
+ "chokidar": "5.0.0",
34
34
  "css-loader": "7.1.4",
35
- "eslint": "10.0.3",
35
+ "eslint": "10.1.0",
36
36
  "fast-glob": "3.3.3",
37
- "find-up": "5.0.0",
37
+ "find-up": "8.0.0",
38
38
  "fs-extra": "11.3.4",
39
39
  "get-yarn-workspaces": "1.0.2",
40
40
  "lodash": "4.17.23",
@@ -42,12 +42,12 @@
42
42
  "process": "0.11.10",
43
43
  "raw-loader": "4.0.2",
44
44
  "react-dom": "18.2.0",
45
- "react-refresh": "0.11.0",
45
+ "react-refresh": "0.18.0",
46
46
  "read-json-sync": "2.0.1",
47
47
  "rimraf": "6.1.3",
48
- "sass": "1.97.3",
48
+ "sass": "1.98.0",
49
49
  "sass-loader": "16.0.7",
50
- "style-loader": "3.3.4",
50
+ "style-loader": "4.0.0",
51
51
  "ts-morph": "27.0.2",
52
52
  "tsx": "4.21.0",
53
53
  "typescript": "5.9.3",
@@ -89,5 +89,5 @@
89
89
  "access": "public",
90
90
  "directory": "."
91
91
  },
92
- "gitHead": "9c6892640a45679ff521e25cd6587dff57393a2e"
92
+ "gitHead": "a3bd3695c66c79238e380d7360d9731b5fcf9c87"
93
93
  }
@@ -1,25 +1,38 @@
1
- import { dirname, relative } from "path";
1
+ import { dirname, join, relative, resolve } from "node:path";
2
2
  import fg from "fast-glob";
3
- import fs from "fs";
3
+ import fs from "node:fs";
4
4
 
5
+ /**
6
+ *
7
+ * @param distDir {String}
8
+ * @param cwd {String}
9
+ * @param debug {Boolean}
10
+ * @returns {Promise<void>}
11
+ */
5
12
  export const replaceTscAliases = async ({ distDir, cwd, debug = false }) => {
6
13
  const dtsFiles = await fg("**/*.d.ts", {
7
14
  cwd: distDir,
8
15
  absolute: true
9
16
  });
10
17
 
18
+ // Build a map of absolute src paths → package names, by scanning sibling packages.
19
+ // This is used to rewrite cross-package src paths (e.g. "../../api/src") back to
20
+ // proper package names (e.g. "@webiny/api") in generated .d.ts files.
21
+ const srcToPackageName = buildSrcToPackageNameMap(cwd);
22
+
11
23
  for (const dtsFile of dtsFiles) {
12
- let content = fs.readFileSync(dtsFile, "utf8");
24
+ let content = fs.readFileSync(dtsFile, "utf8").toString();
13
25
  let modified = false;
14
26
 
15
27
  // Replace all imports/exports with ~/ alias
16
28
  content = content.replace(
17
29
  /(from\s+["'])~\/([^"']+)(["'])/g,
18
- (match, prefix, importPath, suffix) => {
30
+ (_, prefix, importPath, suffix) => {
19
31
  modified = true;
20
32
  // Calculate relative path from current file to dist root
21
- const fileDir = dirname(dtsFile);
22
- const relativePath = relative(fileDir, distDir);
33
+ const fileDir = dirname(dtsFile).replace(/\\/g, "/");
34
+ const normalizedDistDir = distDir.replace(/\\/g, "/");
35
+ const relativePath = relative(fileDir, normalizedDistDir).replace(/\\/g, "/");
23
36
  const finalPath = relativePath
24
37
  ? `${relativePath}/${importPath}`
25
38
  : `./${importPath}`;
@@ -29,11 +42,84 @@ export const replaceTscAliases = async ({ distDir, cwd, debug = false }) => {
29
42
  }
30
43
  );
31
44
 
45
+ // Replace cross-package src paths (e.g. "../../api/src/types") with proper package
46
+ // names (e.g. "@webiny/api/types"). TypeScript inlines these relative paths when
47
+ // project references are used and dependencies have paths pointing to src/.
48
+ if (srcToPackageName.size > 0) {
49
+ content = content.replace(
50
+ /["'](\.\.[^"']*\/src(?:\/[^"']*)?)['"]/g,
51
+ (match, relPath) => {
52
+ const quote = match[0];
53
+ const absPath = resolve(dirname(dtsFile), relPath);
54
+ const packageName = resolveToPackageName(absPath, srcToPackageName);
55
+ if (packageName) {
56
+ modified = true;
57
+ return `${quote}${packageName}${quote}`;
58
+ }
59
+ return match;
60
+ }
61
+ );
62
+ }
63
+
32
64
  if (modified) {
33
65
  fs.writeFileSync(dtsFile, content, "utf8");
34
66
  if (debug) {
35
- console.log(`Resolved ~ aliases in: ${relative(cwd, dtsFile)}`);
67
+ console.log(`Resolved aliases in: ${relative(cwd, dtsFile)}`);
36
68
  }
37
69
  }
38
70
  }
39
71
  };
72
+
73
+ /**
74
+ * Scans sibling packages to build a map of absolute src directory paths → package names.
75
+ * @param {string} cwd - The current package directory.
76
+ * @returns {Map<string, string>}
77
+ */
78
+ function buildSrcToPackageNameMap(cwd) {
79
+ const map = new Map();
80
+ // Go up to the packages/ directory (cwd is packages/xxx, parent is packages/)
81
+ const packagesDir = resolve(cwd, "..");
82
+ if (!fs.existsSync(packagesDir)) {
83
+ return map;
84
+ }
85
+ let entries;
86
+ try {
87
+ entries = fs.readdirSync(packagesDir);
88
+ } catch {
89
+ return map;
90
+ }
91
+ for (const entry of entries) {
92
+ const pkgDir = join(packagesDir, entry);
93
+ const pkgJsonPath = join(pkgDir, "package.json");
94
+ if (!fs.existsSync(pkgJsonPath)) {
95
+ continue;
96
+ }
97
+ try {
98
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
99
+ if (pkgJson.name) {
100
+ const srcDir = join(pkgDir, "src");
101
+ map.set(srcDir, pkgJson.name);
102
+ }
103
+ } catch {
104
+ // ignore
105
+ }
106
+ }
107
+ return map;
108
+ }
109
+
110
+ /**
111
+ * Given an absolute path that points into a package's src directory, returns the
112
+ * corresponding package name + sub-path (e.g. "@webiny/api/types").
113
+ * @param {string} absPath - Absolute path resolved from the relative import.
114
+ * @param {Map<string, string>} srcToPackageName
115
+ * @returns {string|null}
116
+ */
117
+ function resolveToPackageName(absPath, srcToPackageName) {
118
+ for (const [srcDir, packageName] of srcToPackageName) {
119
+ if (absPath === srcDir || absPath.startsWith(srcDir + "/")) {
120
+ const subPath = absPath.slice(srcDir.length).replace(/^\//, "");
121
+ return subPath ? `${packageName}/${subPath}` : packageName;
122
+ }
123
+ }
124
+ return null;
125
+ }
@@ -4,7 +4,10 @@ import merge from "lodash/merge.js";
4
4
  import { replaceTscAliases } from "./tsAliasReplacer.js";
5
5
 
6
6
  export const tsCompile = async ({ cwd = "", overrides, debug }) => {
7
- const tsConfigPath = join(cwd, "tsconfig.build.json");
7
+ // Normalize path separators to forward slashes for consistent behavior on Windows.
8
+ const normalizedCwd = cwd.replace(/\\/g, "/");
9
+
10
+ const tsConfigPath = join(normalizedCwd, "tsconfig.build.json");
8
11
 
9
12
  let { config: readTsConfig } = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
10
13
 
@@ -20,11 +23,10 @@ export const tsCompile = async ({ cwd = "", overrides, debug }) => {
20
23
  console.log(readTsConfig);
21
24
  }
22
25
  }
23
- const parsedJsonConfigFile = ts.parseJsonConfigFileContent(readTsConfig, ts.sys, cwd);
26
+ const parsedJsonConfigFile = ts.parseJsonConfigFileContent(readTsConfig, ts.sys, normalizedCwd);
24
27
 
25
28
  const { projectReferences, options, fileNames, errors } = parsedJsonConfigFile;
26
29
 
27
- // Exclude .d.ts files from TypeScript compilation
28
30
  const filteredFileNames = fileNames.filter(fileName => !fileName.endsWith(".d.ts"));
29
31
 
30
32
  const program = ts.createProgram({
@@ -36,10 +38,12 @@ export const tsCompile = async ({ cwd = "", overrides, debug }) => {
36
38
 
37
39
  const { diagnostics, emitSkipped } = program.emit(
38
40
  undefined, // targetSourceFile
39
- (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
40
- // Only emit files within the current package directory
41
- const relativePath = fileName.replace(cwd, "");
42
- if (fileName.startsWith(cwd) && !relativePath.includes("../")) {
41
+ (fileName, data, writeByteOrderMark) => {
42
+ // Only emit files within the current package directory.
43
+ // Normalize path separators to handle Windows backslashes vs forward slashes.
44
+ const normalizedFileName = fileName.replace(/\\/g, "/");
45
+ const relativePath = normalizedFileName.replace(normalizedCwd, "");
46
+ if (normalizedFileName.startsWith(normalizedCwd) && !relativePath.includes("../")) {
43
47
  ts.sys.writeFile(fileName, data, writeByteOrderMark);
44
48
  }
45
49
  }
@@ -50,7 +54,7 @@ export const tsCompile = async ({ cwd = "", overrides, debug }) => {
50
54
  if (allDiagnostics.length) {
51
55
  const formatHost = {
52
56
  getCanonicalFileName: path => path,
53
- getCurrentDirectory: () => cwd,
57
+ getCurrentDirectory: () => normalizedCwd,
54
58
  getNewLine: () => ts.sys.newLine
55
59
  };
56
60
  const message = ts.formatDiagnostics(allDiagnostics, formatHost);
@@ -64,6 +68,6 @@ export const tsCompile = async ({ cwd = "", overrides, debug }) => {
64
68
  }
65
69
 
66
70
  // Resolve ~ path aliases in .d.ts files
67
- const distDir = options.outDir || join(cwd, "dist");
68
- await replaceTscAliases({ distDir, cwd, debug });
71
+ const distDir = options.outDir || join(normalizedCwd, "dist");
72
+ await replaceTscAliases({ distDir, cwd: normalizedCwd, debug });
69
73
  };
@@ -1,5 +1,6 @@
1
1
  import * as rimraf from "rimraf";
2
2
  import { join } from "path";
3
+ import fs from "node:fs";
3
4
  import { babelCompile } from "./buildPackage/babelCompile.js";
4
5
  import { tsCompile } from "./buildPackage/tsCompile.js";
5
6
  import { copyToDist } from "./buildPackage/copyToDist.js";
@@ -12,8 +13,7 @@ export default async options => {
12
13
  options.cwd = "";
13
14
  }
14
15
  const { cwd = "" } = options;
15
- options.logs !== false && console.log("Deleting existing build files...");
16
- rimraf.sync(join(cwd, "./dist"));
16
+
17
17
  rimraf.sync(join(cwd, "*.tsbuildinfo"), { glob: true });
18
18
 
19
19
  options.logs !== false && console.log("Building...");
@@ -26,6 +26,16 @@ export default async options => {
26
26
  // Validate ESM imports before compiling
27
27
  await validateEsmImports({ cwd, logs: options.logs });
28
28
 
29
+ // Clear dist/ contents without removing the directory itself.
30
+ // node_modules/@webiny/<pkg> symlinks directly to dist/, so deleting
31
+ // the directory would leave a dangling symlink and break Rspack resolution.
32
+ const distDir = join(cwd, "dist");
33
+ if (fs.existsSync(distDir)) {
34
+ for (const entry of fs.readdirSync(distDir)) {
35
+ fs.rmSync(join(distDir, entry), { recursive: true, force: true });
36
+ }
37
+ }
38
+
29
39
  await babelCompile(options);
30
40
  await tsCompile(options);
31
41
 
@@ -1,7 +1,7 @@
1
1
  // We'll use this class once the package is converted to TS!
2
2
 
3
3
  import readJson from "read-json-sync";
4
- import findUp from "find-up";
4
+ import { findUp } from "find-up";
5
5
 
6
6
  export class PackageJson {
7
7
  private readonly filePath: string;
@@ -1,5 +1,5 @@
1
1
  import readJson from "read-json-sync";
2
- import findUp from "find-up";
2
+ import { findUp } from "find-up";
3
3
 
4
4
  export class PackageJson {
5
5
  filePath;