@modern-js/app-tools 1.4.6 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @modern-js/app-tools
2
2
 
3
+ ## 1.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d2d1d6b2: feat: support server config
8
+
9
+ ### Patch Changes
10
+
11
+ - 6aa80baa: fix: Generate config helper file only config file exist
12
+ - Updated dependencies [60855eb2]
13
+ - Updated dependencies [046e58aa]
14
+ - Updated dependencies [ec1b7367]
15
+ - Updated dependencies [77ff9754]
16
+ - Updated dependencies [d2d1d6b2]
17
+ - Updated dependencies [07a4887e]
18
+ - Updated dependencies [ea2ae711]
19
+ - Updated dependencies [17d0cc46]
20
+ - Updated dependencies [d2d1d6b2]
21
+ - @modern-js/core@1.7.0
22
+ - @modern-js/plugin-analyze@1.3.6
23
+ - @modern-js/webpack@1.5.4
24
+ - @modern-js/utils@1.4.0
25
+ - @modern-js/prod-server@1.1.0
26
+ - @modern-js/node-bundle-require@1.3.0
27
+ - @modern-js/types@1.4.0
28
+ - @modern-js/plugin-i18n@1.2.3
29
+ - @modern-js/new-action@1.3.5
30
+ - @modern-js/plugin-fast-refresh@1.2.3
31
+ - @modern-js/server@1.4.9
32
+
3
33
  ## 1.4.6
4
34
 
5
35
  ### Patch Changes
@@ -9,10 +9,10 @@ import { WebpackConfigTarget, getWebpackConfig } from '@modern-js/webpack';
9
9
  import { manager, ResolvedConfigContext } from '@modern-js/core';
10
10
  import { formatWebpackMessages, measureFileSizesBeforeBuild, printFileSizesAfterBuild, printBuildError, logger, isUseSSRBundle, emptyDir } from '@modern-js/utils';
11
11
  import { generateRoutes } from "../utils/routes";
12
+ import { buildServerConfig, emitResolvedConfig } from "../utils/config";
12
13
  // These sizes are pretty large. We'll warn for bundles exceeding them.
13
14
  const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
14
- const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; // eslint-disable-next-line max-statements
15
-
15
+ const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
16
16
  export const build = async (api, options) => {
17
17
  const resolvedConfig = api.useResolvedConfigContext();
18
18
  const appContext = api.useAppContext();
@@ -91,10 +91,17 @@ export const build = async (api, options) => {
91
91
  }));
92
92
  });
93
93
  const {
94
- distDirectory
94
+ distDirectory,
95
+ appDirectory,
96
+ serverConfigFile
95
97
  } = appContext;
96
98
  const previousFileSizes = await measureFileSizesBeforeBuild(distDirectory);
97
99
  await emptyDir(distDirectory);
100
+ await buildServerConfig({
101
+ appDirectory,
102
+ distDirectory,
103
+ configFile: serverConfigFile
104
+ });
98
105
  const buildConfigs = [];
99
106
  buildConfigs.push({
100
107
  type: 'legacy',
@@ -138,4 +145,5 @@ export const build = async (api, options) => {
138
145
 
139
146
  await generateRoutes(appContext);
140
147
  await hookRunners.afterBuild();
148
+ await emitResolvedConfig(appDirectory, resolvedConfig);
141
149
  };
@@ -10,6 +10,7 @@ import { createServer } from "../utils/createServer";
10
10
  import { generateRoutes } from "../utils/routes";
11
11
  import { printInstructions } from "../utils/printInstructions";
12
12
  import { getSpecifiedEntries } from "../utils/getSpecifiedEntries";
13
+ import { buildServerConfig } from "../utils/config";
13
14
  export const dev = async (api, options) => {
14
15
  const appContext = api.useAppContext();
15
16
  const userConfig = api.useResolvedConfigContext();
@@ -19,7 +20,8 @@ export const dev = async (api, options) => {
19
20
  distDirectory,
20
21
  port,
21
22
  existSrc,
22
- entrypoints
23
+ entrypoints,
24
+ serverConfigFile
23
25
  } = appContext;
24
26
  const checkedEntries = await getSpecifiedEntries(options.entry || false, entrypoints);
25
27
  api.setAppContext(_objectSpread(_objectSpread({}, appContext), {}, {
@@ -27,6 +29,16 @@ export const dev = async (api, options) => {
27
29
  }));
28
30
  appContext.checkedEntries = checkedEntries;
29
31
  fs.emptyDirSync(distDirectory);
32
+ await buildServerConfig({
33
+ appDirectory,
34
+ distDirectory,
35
+ configFile: serverConfigFile,
36
+ options: {
37
+ esbuildOptions: {
38
+ watch: true
39
+ }
40
+ }
41
+ });
30
42
  await hookRunners.beforeDev();
31
43
  let compiler = null;
32
44
 
@@ -48,6 +60,7 @@ export const dev = async (api, options) => {
48
60
  const app = await createServer({
49
61
  dev: _objectSpread(_objectSpread({}, {
50
62
  client: {
63
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
51
64
  port: port.toString(),
52
65
  overlay: false,
53
66
  logging: 'none',
@@ -65,6 +78,7 @@ export const dev = async (api, options) => {
65
78
  compiler,
66
79
  pwd: appDirectory,
67
80
  config: userConfig,
81
+ serverConfigFile,
68
82
  plugins: appContext.plugins.filter(p => p.server).map(p => p.server)
69
83
  });
70
84
  app.listen(port, async err => {
@@ -76,7 +90,7 @@ export const dev = async (api, options) => {
76
90
  clearConsole();
77
91
  logger.log(chalk.cyan(`Starting the development server...`));
78
92
  } else {
79
- await printInstructions(api, appContext, userConfig);
93
+ await printInstructions(hookRunners, appContext, userConfig);
80
94
  }
81
95
  });
82
96
  };
@@ -4,21 +4,24 @@ import { printInstructions } from "../utils/printInstructions";
4
4
  export const start = async api => {
5
5
  const appContext = api.useAppContext();
6
6
  const userConfig = api.useResolvedConfigContext();
7
+ const hookRunners = api.useHookRunners();
7
8
  const {
8
9
  appDirectory,
9
- port
10
+ port,
11
+ serverConfigFile
10
12
  } = appContext;
11
13
  logger.log(chalk.cyan(`Starting the modern server...`));
12
14
  const app = await server({
13
15
  pwd: appDirectory,
14
16
  config: userConfig,
15
- plugins: appContext.plugins.filter(p => p.server).map(p => p.server)
17
+ plugins: appContext.plugins.filter(p => p.server).map(p => p.server),
18
+ serverConfigFile
16
19
  });
17
20
  app.listen(port, async err => {
18
21
  if (err) {
19
22
  throw err;
20
23
  }
21
24
 
22
- await printInstructions(api, appContext, userConfig);
25
+ await printInstructions(hookRunners, appContext, userConfig);
23
26
  });
24
27
  };
@@ -0,0 +1 @@
1
+ export { defineServerConfig as defineConfig } from "../utils/config";
@@ -0,0 +1,77 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import * as path from 'path';
8
+ import { bundle } from '@modern-js/node-bundle-require';
9
+ import { CONFIG_FILE_EXTENSIONS, fs, getServerConfig, OUTPUT_CONFIG_FILE } from '@modern-js/utils';
10
+ export const defineServerConfig = config => config;
11
+ export const buildServerConfig = async ({
12
+ appDirectory,
13
+ distDirectory,
14
+ configFile,
15
+ options
16
+ }) => {
17
+ const configFilePath = await getServerConfig(appDirectory, configFile);
18
+
19
+ const getOutputFile = filepath => path.resolve(distDirectory, `${filepath.replace(new RegExp(CONFIG_FILE_EXTENSIONS.join('|')), '')}.js`);
20
+
21
+ if (configFilePath) {
22
+ const configHelperFilePath = path.join(distDirectory, './config-helper.js');
23
+ const helperCode = `
24
+ export const defineConfig = (config) => config;
25
+ `;
26
+ await fs.writeFile(configHelperFilePath, helperCode);
27
+ await bundle(configFilePath, _objectSpread(_objectSpread({}, options), {}, {
28
+ getOutputFile,
29
+ esbuildPlugins: [{
30
+ name: 'native-build-config',
31
+
32
+ setup(ctx) {
33
+ ctx.onResolve({
34
+ filter: /app-tools\/server/
35
+ }, () => {
36
+ return {
37
+ path: configHelperFilePath
38
+ };
39
+ });
40
+ }
41
+
42
+ }]
43
+ }));
44
+ }
45
+ };
46
+ /**
47
+ *
48
+ * 处理循环引用的 replacer
49
+ */
50
+
51
+ export const safeReplacer = () => {
52
+ const cache = [];
53
+ const keyCache = [];
54
+ return function (key, value) {
55
+ if (typeof value === 'object' && value !== null) {
56
+ const index = cache.indexOf(value);
57
+
58
+ if (index !== -1) {
59
+ return `[Circular ${keyCache[index]}]`;
60
+ }
61
+
62
+ cache.push(value);
63
+ keyCache.push(key || 'root');
64
+ }
65
+
66
+ return value;
67
+ };
68
+ };
69
+ export const emitResolvedConfig = async (appDirectory, resolvedConfig) => {
70
+ var _resolvedConfig$outpu;
71
+
72
+ const outputPath = path.join(appDirectory, (resolvedConfig === null || resolvedConfig === void 0 ? void 0 : (_resolvedConfig$outpu = resolvedConfig.output) === null || _resolvedConfig$outpu === void 0 ? void 0 : _resolvedConfig$outpu.path) || './dist', OUTPUT_CONFIG_FILE);
73
+ await fs.writeJSON(outputPath, resolvedConfig, {
74
+ spaces: 2,
75
+ replacer: safeReplacer()
76
+ });
77
+ };
@@ -57,7 +57,7 @@ export const createCompiler = async ({
57
57
  logger.log(chalk.green(`Compiled successfully in ${prettyTime(statsData)} ms.\n`));
58
58
  }
59
59
 
60
- await printInstructions(api, appContext, userConfig);
60
+ await printInstructions(hookRunners, appContext, userConfig);
61
61
  }
62
62
 
63
63
  isFirstCompile = false;
@@ -1,5 +1,5 @@
1
1
  import { prettyInstructions, logger, isDev, chalk } from '@modern-js/utils';
2
- export const printInstructions = async (api, appContext, config) => {
2
+ export const printInstructions = async (hookRunners, appContext, config) => {
3
3
  let message = prettyInstructions(appContext, config);
4
4
  const {
5
5
  existSrc
@@ -10,7 +10,6 @@ export const printInstructions = async (api, appContext, config) => {
10
10
  } // call beforePrintInstructions hook.
11
11
 
12
12
 
13
- const hookRunners = api.useHookRunners();
14
13
  const {
15
14
  instructions
16
15
  } = await hookRunners.beforePrintInstructions({
@@ -15,6 +15,8 @@ var _utils = require("@modern-js/utils");
15
15
 
16
16
  var _routes = require("../utils/routes");
17
17
 
18
+ var _config = require("../utils/config");
19
+
18
20
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
19
21
 
20
22
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -23,7 +25,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
23
25
 
24
26
  // These sizes are pretty large. We'll warn for bundles exceeding them.
25
27
  const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
26
- const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; // eslint-disable-next-line max-statements
28
+ const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
27
29
 
28
30
  const build = async (api, options) => {
29
31
  const resolvedConfig = api.useResolvedConfigContext();
@@ -107,10 +109,17 @@ const build = async (api, options) => {
107
109
  });
108
110
 
109
111
  const {
110
- distDirectory
112
+ distDirectory,
113
+ appDirectory,
114
+ serverConfigFile
111
115
  } = appContext;
112
116
  const previousFileSizes = await (0, _utils.measureFileSizesBeforeBuild)(distDirectory);
113
117
  await (0, _utils.emptyDir)(distDirectory);
118
+ await (0, _config.buildServerConfig)({
119
+ appDirectory,
120
+ distDirectory,
121
+ configFile: serverConfigFile
122
+ });
114
123
  const buildConfigs = [];
115
124
  buildConfigs.push({
116
125
  type: 'legacy',
@@ -154,6 +163,7 @@ const build = async (api, options) => {
154
163
 
155
164
  await (0, _routes.generateRoutes)(appContext);
156
165
  await hookRunners.afterBuild();
166
+ await (0, _config.emitResolvedConfig)(appDirectory, resolvedConfig);
157
167
  };
158
168
 
159
169
  exports.build = build;
@@ -17,6 +17,8 @@ var _printInstructions = require("../utils/printInstructions");
17
17
 
18
18
  var _getSpecifiedEntries = require("../utils/getSpecifiedEntries");
19
19
 
20
+ var _config = require("../utils/config");
21
+
20
22
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
23
 
22
24
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -36,7 +38,8 @@ const dev = async (api, options) => {
36
38
  distDirectory,
37
39
  port,
38
40
  existSrc,
39
- entrypoints
41
+ entrypoints,
42
+ serverConfigFile
40
43
  } = appContext;
41
44
  const checkedEntries = await (0, _getSpecifiedEntries.getSpecifiedEntries)(options.entry || false, entrypoints);
42
45
  api.setAppContext(_objectSpread(_objectSpread({}, appContext), {}, {
@@ -46,6 +49,16 @@ const dev = async (api, options) => {
46
49
 
47
50
  _utils.fs.emptyDirSync(distDirectory);
48
51
 
52
+ await (0, _config.buildServerConfig)({
53
+ appDirectory,
54
+ distDirectory,
55
+ configFile: serverConfigFile,
56
+ options: {
57
+ esbuildOptions: {
58
+ watch: true
59
+ }
60
+ }
61
+ });
49
62
  await hookRunners.beforeDev();
50
63
  let compiler = null;
51
64
 
@@ -67,6 +80,7 @@ const dev = async (api, options) => {
67
80
  const app = await (0, _createServer.createServer)({
68
81
  dev: _objectSpread(_objectSpread({}, {
69
82
  client: {
83
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
70
84
  port: port.toString(),
71
85
  overlay: false,
72
86
  logging: 'none',
@@ -84,6 +98,7 @@ const dev = async (api, options) => {
84
98
  compiler,
85
99
  pwd: appDirectory,
86
100
  config: userConfig,
101
+ serverConfigFile,
87
102
  plugins: appContext.plugins.filter(p => p.server).map(p => p.server)
88
103
  });
89
104
  app.listen(port, async err => {
@@ -96,7 +111,7 @@ const dev = async (api, options) => {
96
111
 
97
112
  _utils.logger.log(_utils.chalk.cyan(`Starting the development server...`));
98
113
  } else {
99
- await (0, _printInstructions.printInstructions)(api, appContext, userConfig);
114
+ await (0, _printInstructions.printInstructions)(hookRunners, appContext, userConfig);
100
115
  }
101
116
  });
102
117
  };
@@ -16,9 +16,11 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
16
16
  const start = async api => {
17
17
  const appContext = api.useAppContext();
18
18
  const userConfig = api.useResolvedConfigContext();
19
+ const hookRunners = api.useHookRunners();
19
20
  const {
20
21
  appDirectory,
21
- port
22
+ port,
23
+ serverConfigFile
22
24
  } = appContext;
23
25
 
24
26
  _utils.logger.log(_utils.chalk.cyan(`Starting the modern server...`));
@@ -26,14 +28,15 @@ const start = async api => {
26
28
  const app = await (0, _prodServer.default)({
27
29
  pwd: appDirectory,
28
30
  config: userConfig,
29
- plugins: appContext.plugins.filter(p => p.server).map(p => p.server)
31
+ plugins: appContext.plugins.filter(p => p.server).map(p => p.server),
32
+ serverConfigFile
30
33
  });
31
34
  app.listen(port, async err => {
32
35
  if (err) {
33
36
  throw err;
34
37
  }
35
38
 
36
- await (0, _printInstructions.printInstructions)(api, appContext, userConfig);
39
+ await (0, _printInstructions.printInstructions)(hookRunners, appContext, userConfig);
37
40
  });
38
41
  };
39
42
 
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "defineConfig", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _config.defineServerConfig;
10
+ }
11
+ });
12
+
13
+ var _config = require("../utils/config");
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.safeReplacer = exports.emitResolvedConfig = exports.defineServerConfig = exports.buildServerConfig = void 0;
7
+
8
+ var path = _interopRequireWildcard(require("path"));
9
+
10
+ var _nodeBundleRequire = require("@modern-js/node-bundle-require");
11
+
12
+ var _utils = require("@modern-js/utils");
13
+
14
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
+
16
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
+
18
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
19
+
20
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
21
+
22
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
23
+
24
+ const defineServerConfig = config => config;
25
+
26
+ exports.defineServerConfig = defineServerConfig;
27
+
28
+ const buildServerConfig = async ({
29
+ appDirectory,
30
+ distDirectory,
31
+ configFile,
32
+ options
33
+ }) => {
34
+ const configFilePath = await (0, _utils.getServerConfig)(appDirectory, configFile);
35
+
36
+ const getOutputFile = filepath => path.resolve(distDirectory, `${filepath.replace(new RegExp(_utils.CONFIG_FILE_EXTENSIONS.join('|')), '')}.js`);
37
+
38
+ if (configFilePath) {
39
+ const configHelperFilePath = path.join(distDirectory, './config-helper.js');
40
+ const helperCode = `
41
+ export const defineConfig = (config) => config;
42
+ `;
43
+ await _utils.fs.writeFile(configHelperFilePath, helperCode);
44
+ await (0, _nodeBundleRequire.bundle)(configFilePath, _objectSpread(_objectSpread({}, options), {}, {
45
+ getOutputFile,
46
+ esbuildPlugins: [{
47
+ name: 'native-build-config',
48
+
49
+ setup(ctx) {
50
+ ctx.onResolve({
51
+ filter: /app-tools\/server/
52
+ }, () => {
53
+ return {
54
+ path: configHelperFilePath
55
+ };
56
+ });
57
+ }
58
+
59
+ }]
60
+ }));
61
+ }
62
+ };
63
+ /**
64
+ *
65
+ * 处理循环引用的 replacer
66
+ */
67
+
68
+
69
+ exports.buildServerConfig = buildServerConfig;
70
+
71
+ const safeReplacer = () => {
72
+ const cache = [];
73
+ const keyCache = [];
74
+ return function (key, value) {
75
+ if (typeof value === 'object' && value !== null) {
76
+ const index = cache.indexOf(value);
77
+
78
+ if (index !== -1) {
79
+ return `[Circular ${keyCache[index]}]`;
80
+ }
81
+
82
+ cache.push(value);
83
+ keyCache.push(key || 'root');
84
+ }
85
+
86
+ return value;
87
+ };
88
+ };
89
+
90
+ exports.safeReplacer = safeReplacer;
91
+
92
+ const emitResolvedConfig = async (appDirectory, resolvedConfig) => {
93
+ var _resolvedConfig$outpu;
94
+
95
+ const outputPath = path.join(appDirectory, (resolvedConfig === null || resolvedConfig === void 0 ? void 0 : (_resolvedConfig$outpu = resolvedConfig.output) === null || _resolvedConfig$outpu === void 0 ? void 0 : _resolvedConfig$outpu.path) || './dist', _utils.OUTPUT_CONFIG_FILE);
96
+ await _utils.fs.writeJSON(outputPath, resolvedConfig, {
97
+ spaces: 2,
98
+ replacer: safeReplacer()
99
+ });
100
+ };
101
+
102
+ exports.emitResolvedConfig = emitResolvedConfig;
@@ -73,7 +73,7 @@ const createCompiler = async ({
73
73
  _utils.logger.log(_utils.chalk.green(`Compiled successfully in ${prettyTime(statsData)} ms.\n`));
74
74
  }
75
75
 
76
- await (0, _printInstructions.printInstructions)(api, appContext, userConfig);
76
+ await (0, _printInstructions.printInstructions)(hookRunners, appContext, userConfig);
77
77
  }
78
78
 
79
79
  isFirstCompile = false;
@@ -7,7 +7,7 @@ exports.printInstructions = void 0;
7
7
 
8
8
  var _utils = require("@modern-js/utils");
9
9
 
10
- const printInstructions = async (api, appContext, config) => {
10
+ const printInstructions = async (hookRunners, appContext, config) => {
11
11
  let message = (0, _utils.prettyInstructions)(appContext, config);
12
12
  const {
13
13
  existSrc
@@ -18,7 +18,6 @@ const printInstructions = async (api, appContext, config) => {
18
18
  } // call beforePrintInstructions hook.
19
19
 
20
20
 
21
- const hookRunners = api.useHookRunners();
22
21
  const {
23
22
  instructions
24
23
  } = await hookRunners.beforePrintInstructions({
@@ -0,0 +1 @@
1
+ export { defineServerConfig as defineConfig } from '../utils/config';
@@ -0,0 +1,22 @@
1
+ import { bundle } from '@modern-js/node-bundle-require';
2
+ import type { NormalizedConfig } from '@modern-js/core';
3
+ import type { ServerConfig } from '@modern-js/server-core';
4
+ export declare const defineServerConfig: (config: ServerConfig) => ServerConfig;
5
+ export declare const buildServerConfig: ({
6
+ appDirectory,
7
+ distDirectory,
8
+ configFile,
9
+ options
10
+ }: {
11
+ appDirectory: string;
12
+ distDirectory: string;
13
+ configFile: string;
14
+ options?: Parameters<typeof bundle>[1];
15
+ }) => Promise<void>;
16
+ /**
17
+ *
18
+ * 处理循环引用的 replacer
19
+ */
20
+
21
+ export declare const safeReplacer: () => (key: string, value: unknown) => unknown;
22
+ export declare const emitResolvedConfig: (appDirectory: string, resolvedConfig: NormalizedConfig) => Promise<void>;
@@ -1,2 +1,2 @@
1
- import type { PluginAPI, IAppContext, NormalizedConfig } from '@modern-js/core';
2
- export declare const printInstructions: (api: PluginAPI, appContext: IAppContext, config: NormalizedConfig) => Promise<void>;
1
+ import type { IAppContext, NormalizedConfig, ToRunners, CliHooks } from '@modern-js/core';
2
+ export declare const printInstructions: (hookRunners: ToRunners<CliHooks>, appContext: IAppContext, config: NormalizedConfig) => Promise<void>;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.4.6",
14
+ "version": "1.5.0",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -33,6 +33,10 @@
33
33
  "./types": {
34
34
  "jsnext:source": "./lib/types.d.ts",
35
35
  "default": "./lib/types.d.ts"
36
+ },
37
+ "./server": {
38
+ "jsnext:source": "./src/exports/server.ts",
39
+ "default": "./dist/js/node/exports/server.js"
36
40
  }
37
41
  },
38
42
  "typesVersions": {
@@ -42,6 +46,9 @@
42
46
  ],
43
47
  "types": [
44
48
  "./lib/types.d.ts"
49
+ ],
50
+ "server": [
51
+ "./dist/types/exports/server.d.ts"
45
52
  ]
46
53
  }
47
54
  },
@@ -50,22 +57,24 @@
50
57
  },
51
58
  "dependencies": {
52
59
  "@babel/runtime": "^7",
53
- "@modern-js/core": "^1.6.1",
60
+ "@modern-js/core": "^1.7.0",
54
61
  "@modern-js/i18n-cli-language-detector": "^1.2.1",
55
- "@modern-js/new-action": "^1.3.3",
62
+ "@modern-js/new-action": "^1.3.5",
63
+ "@modern-js/node-bundle-require": "^1.3.0",
56
64
  "@modern-js/plugin": "^1.3.2",
57
- "@modern-js/plugin-analyze": "^1.3.5",
65
+ "@modern-js/plugin-analyze": "^1.3.6",
58
66
  "@modern-js/plugin-fast-refresh": "^1.2.3",
59
- "@modern-js/plugin-i18n": "^1.2.1",
60
- "@modern-js/prod-server": "^1.0.6",
67
+ "@modern-js/plugin-i18n": "^1.2.3",
68
+ "@modern-js/prod-server": "^1.1.0",
61
69
  "@modern-js/server": "^1.4.9",
62
- "@modern-js/types": "^1.3.6",
63
- "@modern-js/utils": "^1.3.7",
64
- "@modern-js/webpack": "^1.5.3",
70
+ "@modern-js/types": "^1.4.0",
71
+ "@modern-js/utils": "^1.4.0",
72
+ "@modern-js/webpack": "^1.5.4",
65
73
  "inquirer": "^8.2.0",
66
74
  "webpack": "^5.71.0"
67
75
  },
68
76
  "devDependencies": {
77
+ "@modern-js/server-core": "^1.3.0",
69
78
  "@scripts/build": "0.0.0",
70
79
  "@scripts/jest-config": "0.0.0",
71
80
  "@types/inquirer": "^8.2.0",
@@ -0,0 +1,5 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`test app-tools utils safeReplacer should handle circular object 1`] = `"{\\"name\\":\\"a\\",\\"b\\":{\\"name\\":\\"b\\",\\"a\\":\\"[Circular root]\\"}}"`;
4
+
5
+ exports[`test app-tools utils safeReplacer should handle circular object 2`] = `"{\\"name\\":\\"c\\",\\"d\\":{\\"name\\":\\"d\\",\\"e\\":{\\"name\\":\\"e\\",\\"c\\":\\"[Circular root]\\"}}}"`;
@@ -6,6 +6,7 @@ import {
6
6
  getServer,
7
7
  } from '../src/utils/createServer';
8
8
  import { getSpecifiedEntries } from '../src/utils/getSpecifiedEntries';
9
+ import { safeReplacer } from '../src/utils/config';
9
10
 
10
11
  describe('test app-tools utils', () => {
11
12
  it('should return all entryNames correctly', async () => {
@@ -63,4 +64,49 @@ describe('test app-tools utils', () => {
63
64
  await closeServer();
64
65
  expect(getServer()).toBeNull();
65
66
  });
67
+
68
+ it('safeReplacer should handle circular object', () => {
69
+ const a: {
70
+ [key: string]: unknown;
71
+ } = {
72
+ name: 'a',
73
+ };
74
+
75
+ const b: {
76
+ [key: string]: unknown;
77
+ } = {
78
+ name: 'b',
79
+ };
80
+
81
+ a.b = b;
82
+ b.a = a;
83
+
84
+ const res1 = JSON.stringify(a, safeReplacer());
85
+ expect(res1).toMatchSnapshot();
86
+
87
+ const c: {
88
+ [key: string]: unknown;
89
+ } = {
90
+ name: 'c',
91
+ };
92
+
93
+ const d: {
94
+ [key: string]: unknown;
95
+ } = {
96
+ name: 'd',
97
+ };
98
+
99
+ const e: {
100
+ [key: string]: unknown;
101
+ } = {
102
+ name: 'e',
103
+ };
104
+
105
+ c.d = d;
106
+ d.e = e;
107
+ e.c = c;
108
+
109
+ const res2 = JSON.stringify(c, safeReplacer());
110
+ expect(res2).toMatchSnapshot();
111
+ });
66
112
  });