@imtf/profile-scripts 1.5.2 → 2.0.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.
package/bin/profile-scripts.js
CHANGED
|
@@ -7,13 +7,26 @@ const args = process.argv.slice(2);
|
|
|
7
7
|
const scriptIndex = args.findIndex((x) => x === "build" || x === "start");
|
|
8
8
|
const script = scriptIndex === -1 ? args[0] : args[scriptIndex];
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const useVite = args.includes("--vite");
|
|
11
|
+
const useViteFederation = args.includes("--federation");
|
|
12
|
+
|
|
13
|
+
// federation automatically implies vite
|
|
14
|
+
const useViteBuild = useVite || useViteFederation;
|
|
15
|
+
|
|
16
|
+
// Remove internal routing flags before forwarding
|
|
17
|
+
const cleanedArgs = args.filter(
|
|
18
|
+
(arg) => arg !== "--vite"
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const scriptPath = useViteBuild
|
|
22
|
+
? require.resolve("../scripts/viteBuild.mjs")
|
|
23
|
+
: require.resolve("../scripts/esbuild.mjs");
|
|
11
24
|
|
|
12
25
|
switch (script) {
|
|
13
26
|
case "start":
|
|
14
27
|
case "build": {
|
|
15
|
-
const nodeArgs = scriptIndex > 0 ?
|
|
16
|
-
const scriptArgs =
|
|
28
|
+
const nodeArgs = scriptIndex > 0 ? cleanedArgs.slice(0, scriptIndex) : [];
|
|
29
|
+
const scriptArgs = cleanedArgs.slice(scriptIndex + 1);
|
|
17
30
|
|
|
18
31
|
if (script === "start") {
|
|
19
32
|
scriptArgs.push("--watch");
|
package/changelog.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Here you can find a resume of all changes between versions.
|
|
4
4
|
|
|
5
|
+
## 2.0.0
|
|
6
|
+
|
|
7
|
+
### Breaking changes
|
|
8
|
+
|
|
9
|
+
- ViteJS will now be used as the default bundler for development and production builds.
|
|
10
|
+
The previous version of the package used esbuild.
|
|
11
|
+
This change allows Module Federation to be supported.
|
|
12
|
+
|
|
5
13
|
## 1.5.0
|
|
6
14
|
|
|
7
15
|
### Features
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imtf/profile-scripts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.0",
|
|
4
4
|
"description": "Default scripts to bundle & transpile imtf front-end plugins",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"profile-scripts": "bin/profile-scripts.js"
|
|
7
|
+
"profile-scripts": "./bin/profile-scripts.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
|
@@ -19,14 +19,23 @@
|
|
|
19
19
|
"license": "UNLICENSED",
|
|
20
20
|
"private": false,
|
|
21
21
|
"dependencies": {
|
|
22
|
+
"@originjs/vite-plugin-federation": "^1.4.1",
|
|
22
23
|
"@svgr/core": "^8.1.0",
|
|
23
24
|
"@svgr/plugin-jsx": "^8.1.0",
|
|
24
25
|
"@svgr/plugin-svgo": "^8.1.0",
|
|
26
|
+
"@vitejs/plugin-react": "^5.1.4",
|
|
25
27
|
"esbuild": "^0.27.0",
|
|
26
28
|
"esbuild-css-modules-plugin": "^3.1.4",
|
|
27
29
|
"esbuild-plugin-external-global": "^1.0.1",
|
|
28
30
|
"esbuild-plugin-inline-css": "^0.0.1",
|
|
31
|
+
"http-server": "^14.1.1",
|
|
29
32
|
"minimist": "^1.2.8",
|
|
30
|
-
"serve-handler": "^6.1.6"
|
|
33
|
+
"serve-handler": "^6.1.6",
|
|
34
|
+
"vite": "^7.3.1",
|
|
35
|
+
"vite-plugin-css-injected-by-js": "^4.0.1",
|
|
36
|
+
"vite-tsconfig-paths": "^6.1.1"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/minimist": "^1.2.5"
|
|
31
40
|
}
|
|
32
41
|
}
|
package/scripts/esbuild.mjs
CHANGED
|
@@ -3,8 +3,7 @@ import esbuild from "esbuild-plugin-external-global";
|
|
|
3
3
|
import InlineCSSPlugin from "esbuild-plugin-inline-css";
|
|
4
4
|
import CssModulesPlugin from "esbuild-css-modules-plugin";
|
|
5
5
|
import minimist from "minimist";
|
|
6
|
-
import
|
|
7
|
-
import http from "http";
|
|
6
|
+
import HttpServer from "http-server";
|
|
8
7
|
|
|
9
8
|
// eslint-disable-next-line import/no-named-as-default-member
|
|
10
9
|
const externalGlobalPlugin = esbuild.externalGlobalPlugin;
|
|
@@ -88,9 +87,8 @@ if (watch) {
|
|
|
88
87
|
await ctx.watch();
|
|
89
88
|
|
|
90
89
|
// Create a server for the build directory
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
.listen(3010, () => console.log("Running at http://localhost:3010"));
|
|
90
|
+
const server = HttpServer.createServer({ root: "build" });
|
|
91
|
+
server.listen(3010, () => console.log("Running at http://localhost:3010"));
|
|
94
92
|
} else {
|
|
95
93
|
await build(config);
|
|
96
94
|
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
6
|
+
|
|
7
|
+
import http from "http";
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import { pathToFileURL } from "url";
|
|
11
|
+
|
|
12
|
+
import federation from "@originjs/vite-plugin-federation";
|
|
13
|
+
import react from "@vitejs/plugin-react";
|
|
14
|
+
import { transform } from "esbuild";
|
|
15
|
+
import minimist from "minimist";
|
|
16
|
+
import handler from "serve-handler";
|
|
17
|
+
import { build as viteBuild } from "vite";
|
|
18
|
+
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";
|
|
19
|
+
import tsconfigPaths from "vite-tsconfig-paths";
|
|
20
|
+
|
|
21
|
+
import notifierPlugin from "./vitePlugins/viteNotifierPlugin.mjs";
|
|
22
|
+
import svgPlugin from "./vitePlugins/viteSvgPlugin.mjs";
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
watch,
|
|
26
|
+
entryPoint,
|
|
27
|
+
externalGlobal,
|
|
28
|
+
federation: enableFederation,
|
|
29
|
+
} = minimist(process.argv.slice(2));
|
|
30
|
+
|
|
31
|
+
const consumerRoot = process.cwd();
|
|
32
|
+
const outDir = "build";
|
|
33
|
+
|
|
34
|
+
const entryAbs = entryPoint
|
|
35
|
+
? path.resolve(consumerRoot, entryPoint)
|
|
36
|
+
: path.resolve(consumerRoot, "src/index.js");
|
|
37
|
+
|
|
38
|
+
// Force JSX transform for .js files in src
|
|
39
|
+
const jsxPreTransformPlugin = {
|
|
40
|
+
name: "jsx-pre-transform",
|
|
41
|
+
enforce: "pre",
|
|
42
|
+
async transform(code, id) {
|
|
43
|
+
if (id.endsWith(".js") && id.includes(path.resolve(consumerRoot, "src"))) {
|
|
44
|
+
const result = await transform(code, {
|
|
45
|
+
loader: "jsx",
|
|
46
|
+
jsx: "automatic",
|
|
47
|
+
target: "esnext",
|
|
48
|
+
sourcemap: !watch,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
code: result.code,
|
|
53
|
+
map: result.map || null,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Custom plugin to resolve package.json imports from node_modules
|
|
61
|
+
const packageJsonResolver = {
|
|
62
|
+
name: "package-json-resolver",
|
|
63
|
+
enforce: "pre",
|
|
64
|
+
resolveId(source) {
|
|
65
|
+
if (!source.endsWith("/package.json")) return null;
|
|
66
|
+
|
|
67
|
+
const pkgName = source.replace(/\/package\.json$/, "");
|
|
68
|
+
|
|
69
|
+
const resolvedPath = path.resolve(
|
|
70
|
+
consumerRoot,
|
|
71
|
+
"node_modules",
|
|
72
|
+
pkgName,
|
|
73
|
+
"package.json",
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (fs.existsSync(resolvedPath)) {
|
|
77
|
+
return resolvedPath;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return null;
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Parse external globals
|
|
85
|
+
const externalGlobals = externalGlobal
|
|
86
|
+
? (typeof externalGlobal === "string"
|
|
87
|
+
? [externalGlobal]
|
|
88
|
+
: externalGlobal
|
|
89
|
+
).reduce((acc, curr) => {
|
|
90
|
+
const [key, value] = curr.split("=");
|
|
91
|
+
acc[key] = value;
|
|
92
|
+
return acc;
|
|
93
|
+
}, {})
|
|
94
|
+
: {};
|
|
95
|
+
|
|
96
|
+
// Dynamically resolve optional federation.config.(js|mjs) from consumer root
|
|
97
|
+
const resolveFederationConfig = async () => {
|
|
98
|
+
if (!enableFederation) return {};
|
|
99
|
+
|
|
100
|
+
const candidates = ["federation.config.mjs", "federation.config.js"];
|
|
101
|
+
|
|
102
|
+
for (const file of candidates) {
|
|
103
|
+
const fullPath = path.resolve(consumerRoot, file);
|
|
104
|
+
if (fs.existsSync(fullPath)) {
|
|
105
|
+
const mod = await import(pathToFileURL(fullPath).href);
|
|
106
|
+
return mod.default ?? mod;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
throw new Error(
|
|
111
|
+
"[profile-scripts] --federation requires federation.config.(js|mjs) in project root.",
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Vite plugins
|
|
116
|
+
const vitePlugins = [
|
|
117
|
+
// Must run before other plugins: transforms JSX inside .js files
|
|
118
|
+
// so Vite's import analysis can parse them correctly
|
|
119
|
+
jsxPreTransformPlugin,
|
|
120
|
+
|
|
121
|
+
// Custom resolver for package.json imports
|
|
122
|
+
packageJsonResolver,
|
|
123
|
+
|
|
124
|
+
// React JSX transform + automatic runtime
|
|
125
|
+
react({
|
|
126
|
+
jsxRuntime: "automatic",
|
|
127
|
+
include: /\.(js|jsx|ts|tsx)$/,
|
|
128
|
+
}),
|
|
129
|
+
|
|
130
|
+
// Resolve tsconfig path aliases
|
|
131
|
+
tsconfigPaths(),
|
|
132
|
+
|
|
133
|
+
// Inject CSS into the bundle for library consumers without needing separate CSS files
|
|
134
|
+
cssInjectedByJsPlugin(),
|
|
135
|
+
|
|
136
|
+
// Handle SVG as React components or assets
|
|
137
|
+
svgPlugin(),
|
|
138
|
+
|
|
139
|
+
// Log build and rebuild status to console
|
|
140
|
+
notifierPlugin(Boolean(watch)),
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
// Inject Module Federation support when --federation flag is provided
|
|
144
|
+
if (enableFederation) {
|
|
145
|
+
const federationConfig = await resolveFederationConfig();
|
|
146
|
+
|
|
147
|
+
vitePlugins.push(federation(federationConfig));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Vite build configuration
|
|
152
|
+
* @type {import('vite').UserConfig}
|
|
153
|
+
*/
|
|
154
|
+
const viteConfig = {
|
|
155
|
+
root: consumerRoot,
|
|
156
|
+
plugins: vitePlugins,
|
|
157
|
+
logLevel: watch ? "error" : "info", // !!! Need to discuss
|
|
158
|
+
build: {
|
|
159
|
+
outDir,
|
|
160
|
+
emptyOutDir: true,
|
|
161
|
+
target: "esnext",
|
|
162
|
+
sourcemap: watch,
|
|
163
|
+
rollupOptions: {
|
|
164
|
+
input: entryAbs,
|
|
165
|
+
external: [
|
|
166
|
+
"react",
|
|
167
|
+
"react-dom",
|
|
168
|
+
"react-router-dom",
|
|
169
|
+
"IMTFPlugins",
|
|
170
|
+
...Object.keys(externalGlobals),
|
|
171
|
+
],
|
|
172
|
+
output: {
|
|
173
|
+
entryFileNames: "index.js",
|
|
174
|
+
format: "iife",
|
|
175
|
+
inlineDynamicImports: false,
|
|
176
|
+
globals: {
|
|
177
|
+
react: "React",
|
|
178
|
+
"react-dom": "ReactDOM",
|
|
179
|
+
"react-router-dom": "reactRouterDom",
|
|
180
|
+
IMTFPlugins: "IMTFPlugins",
|
|
181
|
+
...externalGlobals,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
minify: watch ? false : process.env.IMTF_MINIFY_WEBAPP !== "false",
|
|
186
|
+
watch: watch ? {} : null,
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Run Vite build in either watch or build mode
|
|
191
|
+
if (watch) {
|
|
192
|
+
await viteBuild(viteConfig);
|
|
193
|
+
|
|
194
|
+
http
|
|
195
|
+
.createServer((...params) => handler(...params, { public: outDir }))
|
|
196
|
+
.listen(3010, () => {
|
|
197
|
+
// eslint-disable-next-line no-console
|
|
198
|
+
console.log("Running at http://localhost:3010");
|
|
199
|
+
});
|
|
200
|
+
} else {
|
|
201
|
+
await viteBuild(viteConfig);
|
|
202
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const viteNotifierPlugin = (watch) => {
|
|
2
|
+
let count = 0;
|
|
3
|
+
|
|
4
|
+
return {
|
|
5
|
+
name: "notifier-plugin-vite",
|
|
6
|
+
|
|
7
|
+
buildStart() {
|
|
8
|
+
count = 0;
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
buildEnd(error) {
|
|
12
|
+
if (error) return;
|
|
13
|
+
|
|
14
|
+
if (count++ === 0) {
|
|
15
|
+
if (watch) {
|
|
16
|
+
console.log(`1st build: ${Date.now()}`);
|
|
17
|
+
} else {
|
|
18
|
+
console.log("Successfully built");
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
console.log(`Rebuilt: ${Date.now()}`);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default viteNotifierPlugin;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const viteSvgPlugin = (options = {}) => {
|
|
2
|
+
return {
|
|
3
|
+
name: "vite-svgr-plugin",
|
|
4
|
+
enforce: "pre",
|
|
5
|
+
async transform(code, id) {
|
|
6
|
+
if (!id.endsWith(".svg")) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const svgPath = id.split("?")[0].split("#")[0];
|
|
10
|
+
|
|
11
|
+
// Read file content
|
|
12
|
+
const svg = await fs.promises.readFile(svgPath, "utf8");
|
|
13
|
+
|
|
14
|
+
// Determine relative path
|
|
15
|
+
const relativePath = path.relative(process.cwd(), svgPath);
|
|
16
|
+
|
|
17
|
+
// This is an asset ==> dataurl
|
|
18
|
+
if (
|
|
19
|
+
!relativePath.startsWith("src/") ||
|
|
20
|
+
relativePath.startsWith("src/assets/")
|
|
21
|
+
) {
|
|
22
|
+
const dataurl = `data:image/svg+xml;base64,${Buffer.from(svg).toString("base64")}`;
|
|
23
|
+
return {
|
|
24
|
+
code: `export default ${JSON.stringify(dataurl)};`,
|
|
25
|
+
map: null
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Otherwise it's a react component
|
|
30
|
+
const contents = await transform(
|
|
31
|
+
svg,
|
|
32
|
+
{
|
|
33
|
+
plugins: ["@svgr/plugin-svgo", "@svgr/plugin-jsx"],
|
|
34
|
+
...options
|
|
35
|
+
},
|
|
36
|
+
{ filePath: svgPath }
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
code: contents,
|
|
41
|
+
map: null
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default viteSvgPlugin;
|