@unpackjs/plugin-react 1.4.4 → 1.5.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/dist/index.cjs CHANGED
@@ -36,6 +36,7 @@ var import_react_refresh_webpack_plugin = __toESM(require("@pmmmwh/react-refresh
36
36
  var import_plugin_react_refresh = __toESM(require("@rspack/plugin-react-refresh"));
37
37
  var import_shared = require("@unpackjs/shared");
38
38
  var import_click_to_component = require("./click-to-component/index.cjs");
39
+ var import_mpa = require("./mpa.cjs");
39
40
  const PLUGIN_NAME = "unpack:react";
40
41
  const pluginReact = (options = {}) => {
41
42
  return {
@@ -45,6 +46,7 @@ const pluginReact = (options = {}) => {
45
46
  if (options.clickToComponent) {
46
47
  next = await (0, import_click_to_component.addClickToComponentSupport)({ config, bundler });
47
48
  }
49
+ next = (0, import_mpa.addMpaSupport)({ config, unpackConfig });
48
50
  const jsExclude = [/node_modules[\\/](?!\.unpack)/];
49
51
  const swcLoader = unpackConfig.bundler === "rspack" ? "builtin:swc-loader" : require.resolve("swc-loader");
50
52
  const ReactRefreshPlugin = unpackConfig.bundler === "rspack" ? import_plugin_react_refresh.default : import_react_refresh_webpack_plugin.default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAe,MAAM,kBAAkB,CAAA;AAGjE,eAAO,MAAM,WAAW,iBAAiB,CAAA;AAEzC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA;AAED,eAAO,MAAM,WAAW,aAAa,kBAAkB,KAAQ,YAkE9D,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAe,MAAM,kBAAkB,CAAA;AAIjE,eAAO,MAAM,WAAW,iBAAiB,CAAA;AAEzC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA;AACD,eAAO,MAAM,WAAW,aAAa,kBAAkB,KAAQ,YAmE9D,CAAA"}
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ import WebpackReactRefreshPlugin from "@pmmmwh/react-refresh-webpack-plugin";
12
12
  import RspackReactRefreshPlugin from "@rspack/plugin-react-refresh";
13
13
  import { isDevServer } from "@unpackjs/shared";
14
14
  import { addClickToComponentSupport } from "./click-to-component/index.js";
15
+ import { addMpaSupport } from "./mpa.js";
15
16
  const PLUGIN_NAME = "unpack:react";
16
17
  const pluginReact = (options = {}) => {
17
18
  return {
@@ -21,6 +22,7 @@ const pluginReact = (options = {}) => {
21
22
  if (options.clickToComponent) {
22
23
  next = await addClickToComponentSupport({ config, bundler });
23
24
  }
25
+ next = addMpaSupport({ config, unpackConfig });
24
26
  const jsExclude = [/node_modules[\\/](?!\.unpack)/];
25
27
  const swcLoader = unpackConfig.bundler === "rspack" ? "builtin:swc-loader" : require.resolve("swc-loader");
26
28
  const ReactRefreshPlugin = unpackConfig.bundler === "rspack" ? RspackReactRefreshPlugin : WebpackReactRefreshPlugin;
package/dist/mpa.cjs ADDED
@@ -0,0 +1,154 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var mpa_exports = {};
29
+ __export(mpa_exports, {
30
+ addMpaSupport: () => addMpaSupport
31
+ });
32
+ module.exports = __toCommonJS(mpa_exports);
33
+ var import_node_fs = __toESM(require("node:fs"));
34
+ var import_node_path = __toESM(require("node:path"));
35
+ var import_shared = require("@unpackjs/shared");
36
+ var import_html_webpack_plugin = __toESM(require("html-webpack-plugin"));
37
+ const addMpaSupport = ({
38
+ config,
39
+ unpackConfig
40
+ }) => {
41
+ if (!unpackConfig.mpa)
42
+ return config;
43
+ const tempDirectory = import_node_path.default.join(import_shared.TEMP_DIR, "mpa");
44
+ const userOptions = (0, import_shared.isPlainObject)(unpackConfig.mpa) ? unpackConfig.mpa : {};
45
+ const getPageConfig = (indexPath) => {
46
+ const filePath = import_node_path.default.join(indexPath, "../config.json");
47
+ let config2 = {};
48
+ if (import_node_fs.default.existsSync(filePath)) {
49
+ config2 = JSON.parse(import_node_fs.default.readFileSync(filePath, "utf-8"));
50
+ }
51
+ return config2;
52
+ };
53
+ const getPathInJs = (absPath) => {
54
+ return JSON.stringify(absPath).slice(1, -1);
55
+ };
56
+ const getAbsPathForEntry = (_path) => {
57
+ const absPath = import_node_path.default.join(unpackConfig.root, _path);
58
+ const validPath = import_node_fs.default.existsSync(absPath) ? absPath : _path;
59
+ return getPathInJs(validPath);
60
+ };
61
+ const createTempFile = (entry2) => {
62
+ import_node_fs.default.rmSync(import_node_path.default.join(unpackConfig.root, tempDirectory), { recursive: true, force: true });
63
+ const globalImport = userOptions.globalImport?.reduce((acc, curr) => {
64
+ return `${acc}
65
+ import '${getAbsPathForEntry(curr)}';`.trimStart();
66
+ }, "") || "";
67
+ const { layout } = userOptions;
68
+ const layoutImport = layout ? `import Layout from '${getAbsPathForEntry(layout)}';` : "";
69
+ const layoutJSX = layout ? "<Layout><App /></Layout>" : "<App />";
70
+ const rootElement = `document.getElementById('${unpackConfig.html?.mountId}')`;
71
+ const reactDOMSource = "react-dom/client";
72
+ const renderer = `ReactDOM.createRoot(${rootElement}).render(${layoutJSX});`;
73
+ Object.entries(entry2).forEach(([entryName, config2]) => {
74
+ const filePath = import_node_path.default.join(unpackConfig.root, tempDirectory, `${entryName}.jsx`);
75
+ const tpl = `
76
+ // DO NOT CHANGE IT MANUALLY!
77
+ import React from 'react';
78
+ import ReactDOM from '${reactDOMSource}';
79
+ import App from '${getPathInJs(config2.import[0])}';${layoutImport && `
80
+ ${layoutImport}`}
81
+ ${globalImport}
82
+ ${renderer}
83
+ `.trimStart();
84
+ const dir = import_node_path.default.dirname(filePath);
85
+ if (!import_node_fs.default.existsSync(dir)) {
86
+ import_node_fs.default.mkdirSync(dir, { recursive: true });
87
+ }
88
+ import_node_fs.default.writeFileSync(filePath, tpl, "utf-8");
89
+ config2.import[0] = filePath;
90
+ });
91
+ return entry2;
92
+ };
93
+ const collectEntry = () => {
94
+ const start = performance.now();
95
+ const entry2 = {};
96
+ const html2 = [];
97
+ const getIndexFilePath = (dir) => {
98
+ const extensions = [".tsx", ".jsx"];
99
+ for (const extension of extensions) {
100
+ const indexFilePath = import_node_path.default.join(dir, `index${extension}`);
101
+ if (import_node_fs.default.existsSync(indexFilePath)) {
102
+ return indexFilePath;
103
+ }
104
+ }
105
+ return null;
106
+ };
107
+ const pagesRoot = import_node_path.default.join(unpackConfig.root, "src", "pages");
108
+ import_node_fs.default.readdirSync(pagesRoot).forEach((filename) => {
109
+ if (filename.startsWith("."))
110
+ return;
111
+ const indexFilePath = getIndexFilePath(import_node_path.default.join(pagesRoot, filename));
112
+ if (indexFilePath) {
113
+ const pageConfig = getPageConfig(indexFilePath);
114
+ let entryName = userOptions.lowerCase === true ? filename.toLowerCase() : filename;
115
+ if (pageConfig.filename) {
116
+ entryName = pageConfig.filename.slice(0, -5);
117
+ }
118
+ entry2[entryName] = {
119
+ import: [indexFilePath]
120
+ };
121
+ if (pageConfig.template) {
122
+ pageConfig.template = import_node_path.default.join(indexFilePath, "../", pageConfig.template);
123
+ }
124
+ html2.push({
125
+ template: unpackConfig.html?.template || "",
126
+ templateContent: unpackConfig.html?.templateContent || import_shared.TEMPLATE_CONTENT,
127
+ minify: false,
128
+ filename: `${entryName}.html`,
129
+ chunks: [entryName],
130
+ ...pageConfig,
131
+ templateParameters: {
132
+ mountId: unpackConfig.html?.mountId,
133
+ title: (0, import_shared.isFunction)(unpackConfig.html?.title) ? unpackConfig.html?.title({ entryName }) : unpackConfig.html?.title,
134
+ headTag: unpackConfig.html?.headTag,
135
+ ...unpackConfig.html?.templateParameters,
136
+ ...pageConfig.templateParameters
137
+ }
138
+ });
139
+ }
140
+ });
141
+ !(0, import_shared.isDevServer)() && import_shared.logger.info(
142
+ `Collect entries in ${(performance.now() - start).toFixed(2)}ms ${import_shared.colors.dim("[MPA]")}`
143
+ );
144
+ return { entry: entry2, html: html2 };
145
+ };
146
+ const { entry, html } = collectEntry();
147
+ config.entry = createTempFile(entry);
148
+ config.plugins.push(...html.map((h) => new import_html_webpack_plugin.default(h)));
149
+ return config;
150
+ };
151
+ // Annotate the CommonJS export names for ESM import in node:
152
+ 0 && (module.exports = {
153
+ addMpaSupport
154
+ });
package/dist/mpa.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { type BundlerConfiguration, type UnpackConfig } from '@unpackjs/shared';
2
+ export declare const addMpaSupport: ({ config, unpackConfig, }: {
3
+ config: BundlerConfiguration;
4
+ unpackConfig: UnpackConfig;
5
+ }) => BundlerConfiguration;
6
+ //# sourceMappingURL=mpa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mpa.d.ts","sourceRoot":"","sources":["../src/mpa.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,oBAAoB,EAGzB,KAAK,YAAY,EAMlB,MAAM,kBAAkB,CAAA;AAazB,eAAO,MAAM,aAAa,8BAGvB;IACD,MAAM,EAAE,oBAAoB,CAAA;IAC5B,YAAY,EAAE,YAAY,CAAA;CAC3B,KAAG,oBAkHH,CAAA"}
package/dist/mpa.js ADDED
@@ -0,0 +1,138 @@
1
+ import { createRequire } from 'node:module';
2
+ var require = createRequire(import.meta['url']);
3
+
4
+ import path from "path";
5
+ import { fileURLToPath } from "url";
6
+ var getFilename = () => fileURLToPath(import.meta.url);
7
+ var getDirname = () => path.dirname(getFilename());
8
+ var __dirname = /* @__PURE__ */ getDirname();
9
+ var __filename = /* @__PURE__ */ getFilename();
10
+ import fs from "node:fs";
11
+ import path2 from "node:path";
12
+ import {
13
+ TEMPLATE_CONTENT,
14
+ TEMP_DIR,
15
+ colors,
16
+ isDevServer,
17
+ isFunction,
18
+ isPlainObject,
19
+ logger
20
+ } from "@unpackjs/shared";
21
+ import HtmlWebpackPlugin from "html-webpack-plugin";
22
+ const addMpaSupport = ({
23
+ config,
24
+ unpackConfig
25
+ }) => {
26
+ if (!unpackConfig.mpa)
27
+ return config;
28
+ const tempDirectory = path2.join(TEMP_DIR, "mpa");
29
+ const userOptions = isPlainObject(unpackConfig.mpa) ? unpackConfig.mpa : {};
30
+ const getPageConfig = (indexPath) => {
31
+ const filePath = path2.join(indexPath, "../config.json");
32
+ let config2 = {};
33
+ if (fs.existsSync(filePath)) {
34
+ config2 = JSON.parse(fs.readFileSync(filePath, "utf-8"));
35
+ }
36
+ return config2;
37
+ };
38
+ const getPathInJs = (absPath) => {
39
+ return JSON.stringify(absPath).slice(1, -1);
40
+ };
41
+ const getAbsPathForEntry = (_path) => {
42
+ const absPath = path2.join(unpackConfig.root, _path);
43
+ const validPath = fs.existsSync(absPath) ? absPath : _path;
44
+ return getPathInJs(validPath);
45
+ };
46
+ const createTempFile = (entry2) => {
47
+ fs.rmSync(path2.join(unpackConfig.root, tempDirectory), { recursive: true, force: true });
48
+ const globalImport = userOptions.globalImport?.reduce((acc, curr) => {
49
+ return `${acc}
50
+ import '${getAbsPathForEntry(curr)}';`.trimStart();
51
+ }, "") || "";
52
+ const { layout } = userOptions;
53
+ const layoutImport = layout ? `import Layout from '${getAbsPathForEntry(layout)}';` : "";
54
+ const layoutJSX = layout ? "<Layout><App /></Layout>" : "<App />";
55
+ const rootElement = `document.getElementById('${unpackConfig.html?.mountId}')`;
56
+ const reactDOMSource = "react-dom/client";
57
+ const renderer = `ReactDOM.createRoot(${rootElement}).render(${layoutJSX});`;
58
+ Object.entries(entry2).forEach(([entryName, config2]) => {
59
+ const filePath = path2.join(unpackConfig.root, tempDirectory, `${entryName}.jsx`);
60
+ const tpl = `
61
+ // DO NOT CHANGE IT MANUALLY!
62
+ import React from 'react';
63
+ import ReactDOM from '${reactDOMSource}';
64
+ import App from '${getPathInJs(config2.import[0])}';${layoutImport && `
65
+ ${layoutImport}`}
66
+ ${globalImport}
67
+ ${renderer}
68
+ `.trimStart();
69
+ const dir = path2.dirname(filePath);
70
+ if (!fs.existsSync(dir)) {
71
+ fs.mkdirSync(dir, { recursive: true });
72
+ }
73
+ fs.writeFileSync(filePath, tpl, "utf-8");
74
+ config2.import[0] = filePath;
75
+ });
76
+ return entry2;
77
+ };
78
+ const collectEntry = () => {
79
+ const start = performance.now();
80
+ const entry2 = {};
81
+ const html2 = [];
82
+ const getIndexFilePath = (dir) => {
83
+ const extensions = [".tsx", ".jsx"];
84
+ for (const extension of extensions) {
85
+ const indexFilePath = path2.join(dir, `index${extension}`);
86
+ if (fs.existsSync(indexFilePath)) {
87
+ return indexFilePath;
88
+ }
89
+ }
90
+ return null;
91
+ };
92
+ const pagesRoot = path2.join(unpackConfig.root, "src", "pages");
93
+ fs.readdirSync(pagesRoot).forEach((filename) => {
94
+ if (filename.startsWith("."))
95
+ return;
96
+ const indexFilePath = getIndexFilePath(path2.join(pagesRoot, filename));
97
+ if (indexFilePath) {
98
+ const pageConfig = getPageConfig(indexFilePath);
99
+ let entryName = userOptions.lowerCase === true ? filename.toLowerCase() : filename;
100
+ if (pageConfig.filename) {
101
+ entryName = pageConfig.filename.slice(0, -5);
102
+ }
103
+ entry2[entryName] = {
104
+ import: [indexFilePath]
105
+ };
106
+ if (pageConfig.template) {
107
+ pageConfig.template = path2.join(indexFilePath, "../", pageConfig.template);
108
+ }
109
+ html2.push({
110
+ template: unpackConfig.html?.template || "",
111
+ templateContent: unpackConfig.html?.templateContent || TEMPLATE_CONTENT,
112
+ minify: false,
113
+ filename: `${entryName}.html`,
114
+ chunks: [entryName],
115
+ ...pageConfig,
116
+ templateParameters: {
117
+ mountId: unpackConfig.html?.mountId,
118
+ title: isFunction(unpackConfig.html?.title) ? unpackConfig.html?.title({ entryName }) : unpackConfig.html?.title,
119
+ headTag: unpackConfig.html?.headTag,
120
+ ...unpackConfig.html?.templateParameters,
121
+ ...pageConfig.templateParameters
122
+ }
123
+ });
124
+ }
125
+ });
126
+ !isDevServer() && logger.info(
127
+ `Collect entries in ${(performance.now() - start).toFixed(2)}ms ${colors.dim("[MPA]")}`
128
+ );
129
+ return { entry: entry2, html: html2 };
130
+ };
131
+ const { entry, html } = collectEntry();
132
+ config.entry = createTempFile(entry);
133
+ config.plugins.push(...html.map((h) => new HtmlWebpackPlugin(h)));
134
+ return config;
135
+ };
136
+ export {
137
+ addMpaSupport
138
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unpackjs/plugin-react",
3
- "version": "1.4.4",
3
+ "version": "1.5.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "exports": {
@@ -30,7 +30,8 @@
30
30
  "@swc/core": "1.7.28",
31
31
  "@swc/helpers": "0.5.13",
32
32
  "launch-editor": "2.9.1",
33
- "@unpackjs/shared": "^1.4.4"
33
+ "html-webpack-plugin": "5.6.0",
34
+ "@unpackjs/shared": "^1.5.0"
34
35
  },
35
36
  "scripts": {
36
37
  "dev": "modern build --watch",