@shuvi/service 1.0.0-rc.9 → 1.0.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.
Files changed (71) hide show
  1. package/lib/bundler/bundler.d.ts +1 -0
  2. package/lib/bundler/bundler.js +49 -25
  3. package/lib/bundler/config.js +14 -14
  4. package/lib/bundler/helper/getOnline.d.ts +1 -0
  5. package/lib/bundler/helper/getOnline.js +42 -0
  6. package/lib/bundler/runCompiler.d.ts +1 -1
  7. package/lib/bundler/typescript/getTypeScriptInfo.d.ts +1 -1
  8. package/lib/bundler/typescript/getTypeScriptInfo.js +6 -5
  9. package/lib/bundler/typescript/installDependencies.d.ts +26 -0
  10. package/lib/bundler/typescript/installDependencies.js +153 -0
  11. package/lib/bundler/typescript/setupTypeScript.d.ts +1 -1
  12. package/lib/bundler/typescript/setupTypeScript.js +25 -6
  13. package/lib/config/config.d.ts +7 -0
  14. package/lib/config/config.js +53 -0
  15. package/lib/config/env.d.ts +15 -0
  16. package/lib/config/env.js +117 -0
  17. package/lib/config/index.d.ts +1 -0
  18. package/lib/config/index.js +5 -0
  19. package/lib/constants.d.ts +3 -8
  20. package/lib/constants.js +6 -12
  21. package/lib/core/api.d.ts +15 -8
  22. package/lib/core/api.js +26 -11
  23. package/lib/core/apiTypes.d.ts +44 -60
  24. package/lib/core/config.js +4 -5
  25. package/lib/core/getPlugins.d.ts +8 -6
  26. package/lib/core/getPlugins.js +179 -93
  27. package/lib/core/paths.d.ts +0 -1
  28. package/lib/core/paths.js +15 -13
  29. package/lib/core/plugin.d.ts +3 -2
  30. package/lib/core/plugin.js +1 -1
  31. package/lib/core/pluginTypes.d.ts +1 -1
  32. package/lib/index.d.ts +1 -1
  33. package/lib/lib/webpack-watch-wait-for-file-builder-plugin.js +1 -1
  34. package/lib/project/file-builder/fileBuilder.js +7 -2
  35. package/lib/project/file-builder/types.d.ts +7 -4
  36. package/lib/project/file-utils/getModuleExports.js +44 -7
  37. package/lib/project/projectContext.d.ts +1 -9
  38. package/lib/project/projectContext.js +1 -2
  39. package/lib/resources.d.ts +4 -4
  40. package/lib/resources.js +15 -5
  41. package/lib/server/http-server/server.js +2 -1
  42. package/lib/server/middlewares/dev/devMiddleware.d.ts +1 -1
  43. package/lib/server/middlewares/dev/devMiddleware.js +60 -67
  44. package/lib/server/middlewares/getAssetMiddleware.js +2 -2
  45. package/lib/server/plugin.d.ts +1 -0
  46. package/lib/server/plugin.js +1 -1
  47. package/lib/server/shuviDevServer.d.ts +5 -0
  48. package/lib/server/shuviDevServer.js +133 -5
  49. package/lib/server/shuviServer.d.ts +2 -0
  50. package/lib/server/shuviServer.js +15 -20
  51. package/package.json +11 -10
  52. package/lib/project/file-manager/defineFile/index.d.ts +0 -16
  53. package/lib/project/file-manager/defineFile/index.js +0 -131
  54. package/lib/project/file-manager/errorHandling.d.ts +0 -1
  55. package/lib/project/file-manager/errorHandling.js +0 -14
  56. package/lib/project/file-manager/file.d.ts +0 -17
  57. package/lib/project/file-manager/file.js +0 -166
  58. package/lib/project/file-manager/fileManager.d.ts +0 -16
  59. package/lib/project/file-manager/fileManager.js +0 -179
  60. package/lib/project/file-manager/fileTypes.d.ts +0 -62
  61. package/lib/project/file-manager/fileTypes.js +0 -2
  62. package/lib/project/file-manager/index.d.ts +0 -8
  63. package/lib/project/file-manager/index.js +0 -12
  64. package/lib/project/file-manager/lifecycle.d.ts +0 -7
  65. package/lib/project/file-manager/lifecycle.js +0 -44
  66. package/lib/project/file-manager/mount.d.ts +0 -4
  67. package/lib/project/file-manager/mount.js +0 -126
  68. package/lib/project/file-manager/scheduler.d.ts +0 -35
  69. package/lib/project/file-manager/scheduler.js +0 -170
  70. package/lib/project/file-manager/utils.d.ts +0 -1
  71. package/lib/project/file-manager/utils.js +0 -9
@@ -17,6 +17,7 @@ export interface NormalizedBundlerOptions {
17
17
  }
18
18
  export declare type BundlerOptions = Partial<NormalizedBundlerOptions>;
19
19
  export interface Bunlder {
20
+ targets: Target[];
20
21
  watching: Watching;
21
22
  watch(): Watching;
22
23
  build(): Promise<BundlerResult>;
@@ -42,7 +42,7 @@ const forkTsCheckerWebpackPlugin_1 = __importStar(require("@shuvi/toolpack/lib/u
42
42
  const formatWebpackMessages_1 = __importDefault(require("@shuvi/toolpack/lib/utils/formatWebpackMessages"));
43
43
  const logger_1 = __importDefault(require("@shuvi/utils/lib/logger"));
44
44
  const util_1 = require("util");
45
- const webpack_1 = __importStar(require("@shuvi/toolpack/lib/webpack"));
45
+ const webpack_1 = require("@shuvi/toolpack/lib/webpack");
46
46
  const config_1 = require("@shuvi/toolpack/lib/webpack/config");
47
47
  const constants_1 = require("@shuvi/shared/lib/constants");
48
48
  const error_1 = require("../error");
@@ -55,7 +55,6 @@ const defaultBundleOptions = {
55
55
  preBundle: false,
56
56
  ignoreTypeScriptErrors: false
57
57
  };
58
- const logger = (0, logger_1.default)('shuvi:bundler');
59
58
  const hasEntry = (chain) => chain.entryPoints.values().length > 0;
60
59
  class WebpackBundler {
61
60
  constructor(options, cliContext) {
@@ -66,6 +65,8 @@ class WebpackBundler {
66
65
  this._watching = new watchingProxy_1.WatchingProxy();
67
66
  this._devMiddlewares = [];
68
67
  this._inited = false;
68
+ this._startTime = null;
69
+ this._isCompiling = false;
69
70
  this._options = options;
70
71
  this._cliContext = cliContext;
71
72
  }
@@ -81,7 +82,7 @@ class WebpackBundler {
81
82
  rootDir: this._cliContext.paths.rootDir,
82
83
  exclude: [/react-refresh/],
83
84
  resolveWebpackModule(module) {
84
- return require(`${webpack_1.webpackResolveContext}/${module}`);
85
+ return (0, webpack_1.resolveWebpackModule)(module);
85
86
  }
86
87
  });
87
88
  this._devMiddlewares.push(dynamicDll.middleware);
@@ -113,7 +114,7 @@ class WebpackBundler {
113
114
  return this._watching;
114
115
  }
115
116
  this._targets.forEach(({ name }) => {
116
- if (name === constants_1.BUNDLER_DEFAULT_TARGET) {
117
+ if (name === constants_1.BUNDLER_TARGET_CLIENT) {
117
118
  this._setupListenersForTarget(name, {
118
119
  typeChecking: true
119
120
  });
@@ -134,7 +135,7 @@ class WebpackBundler {
134
135
  return __awaiter(this, void 0, void 0, function* () {
135
136
  const compiler = this._compiler;
136
137
  if (this._options.ignoreTypeScriptErrors) {
137
- console.log('Skipping validation of types');
138
+ logger_1.default.info('Skipping validation of types');
138
139
  this._compiler.compilers.forEach(compiler => {
139
140
  forkTsCheckerWebpackPlugin_1.default.getCompilerHooks(compiler).issues.tap('afterTypeScriptCheck', (issues) => issues.filter(msg => msg.severity !== 'error'));
140
141
  });
@@ -147,12 +148,15 @@ class WebpackBundler {
147
148
  return yield this._getTargets();
148
149
  });
149
150
  }
151
+ get targets() {
152
+ return this._targets;
153
+ }
150
154
  _getWebpackCompiler(dynamicDll) {
151
155
  return __awaiter(this, void 0, void 0, function* () {
152
156
  if (!this._compiler) {
153
157
  this._targets = yield this._getTargets();
154
158
  if (dynamicDll) {
155
- this._compiler = (0, webpack_1.default)(this._targets.map(({ config }) => {
159
+ this._compiler = (0, webpack_1.webpack)(this._targets.map(({ config }) => {
156
160
  if (config.target === 'node') {
157
161
  return config;
158
162
  }
@@ -160,12 +164,22 @@ class WebpackBundler {
160
164
  }));
161
165
  }
162
166
  else {
163
- this._compiler = (0, webpack_1.default)(this._targets.map(t => t.config));
167
+ this._compiler = (0, webpack_1.webpack)(this._targets.map(t => t.config));
164
168
  }
165
169
  let isFirstSuccessfulCompile = true;
166
170
  this._compiler.hooks.done.tap('done', (stats) => __awaiter(this, void 0, void 0, function* () {
167
171
  const warnings = [];
168
172
  const errors = [];
173
+ this._isCompiling = false;
174
+ let timeMessage = '';
175
+ if (this._startTime) {
176
+ const time = performance.now() - this._startTime;
177
+ this._startTime = 0;
178
+ timeMessage =
179
+ time > 2000
180
+ ? ` in ${Math.round(time / 100) / 10}s`
181
+ : ` in ${Math.ceil(time)} ms`;
182
+ }
169
183
  stats.stats.forEach(s => {
170
184
  const statsData = s.toJson({
171
185
  all: false,
@@ -177,13 +191,24 @@ class WebpackBundler {
177
191
  });
178
192
  const isSuccessful = !warnings.length && !errors.length;
179
193
  if (isSuccessful) {
194
+ if (!isFirstSuccessfulCompile) {
195
+ logger_1.default.info(`Compiled client and server successfully${timeMessage}`);
196
+ }
180
197
  setImmediate(first => {
181
198
  // make sure this event is fired after all bundler:target-done
182
199
  this._cliContext.pluginRunner.afterBundlerDone({ first, stats });
183
200
  }, isFirstSuccessfulCompile);
184
201
  isFirstSuccessfulCompile = false;
185
202
  }
203
+ //reset the startTime
204
+ this._startTime = null;
186
205
  }));
206
+ this._compiler.hooks.invalid.tap('invalid', () => {
207
+ if (!this._isCompiling) {
208
+ this._isCompiling = true;
209
+ logger_1.default.info('Compiling client and server...');
210
+ }
211
+ });
187
212
  }
188
213
  return this._compiler;
189
214
  });
@@ -204,13 +229,11 @@ class WebpackBundler {
204
229
  let tsMessagesPromise;
205
230
  let tsMessagesResolver;
206
231
  let isInvalid = true;
207
- const _log = (...args) => console.log(`[${name}]`, ...args);
208
- const _error = (...args) => console.error(`[${name}]`, ...args);
209
- const _warn = (...args) => console.warn(`[${name}]`, ...args);
232
+ const _error = (...args) => logger_1.default.error(`[${name}]`, ...args);
233
+ const _warn = (...args) => logger_1.default.warn(`[${name}]`, ...args);
210
234
  compiler.hooks.invalid.tap(`invalid`, () => {
211
235
  tsMessagesPromise = undefined;
212
236
  isInvalid = true;
213
- _log('Compiling...');
214
237
  });
215
238
  const useTypeScript = !!((_a = compiler.options.plugins) === null || _a === void 0 ? void 0 : _a.find(plugin => plugin instanceof forkTsCheckerWebpackPlugin_1.default));
216
239
  if (options.typeChecking && useTypeScript) {
@@ -238,6 +261,11 @@ class WebpackBundler {
238
261
  return issues;
239
262
  });
240
263
  }
264
+ compiler.hooks.beforeCompile.tap('beforeCompile', () => {
265
+ if (this._startTime === null) {
266
+ this._startTime = performance.now();
267
+ }
268
+ });
241
269
  // "done" event fires when Webpack has finished recompiling the bundle.
242
270
  // Whether or not you have warnings or errors, you will get this event.
243
271
  compiler.hooks.done.tap('done', (stats) => __awaiter(this, void 0, void 0, function* () {
@@ -261,7 +289,6 @@ class WebpackBundler {
261
289
  const messages = (0, formatWebpackMessages_1.default)(statsData);
262
290
  const isSuccessful = !((_b = messages.errors) === null || _b === void 0 ? void 0 : _b.length) && !((_c = messages.warnings) === null || _c === void 0 ? void 0 : _c.length);
263
291
  if (isSuccessful) {
264
- _log('Compiled successfully!');
265
292
  yield this._cliContext.pluginRunner.afterBundlerTargetDone({
266
293
  first: isFirstSuccessfulCompile,
267
294
  name: compiler.name,
@@ -313,16 +340,16 @@ class WebpackBundler {
313
340
  _initDefaultBuildTarget() {
314
341
  const defaultWebpackHelpers = (0, config_1.webpackHelpers)();
315
342
  const defaultChain = (0, config_2.createWebpackConfig)(this._cliContext, {
316
- name: constants_1.BUNDLER_DEFAULT_TARGET,
343
+ name: constants_1.BUNDLER_TARGET_CLIENT,
317
344
  node: false,
318
345
  entry: {},
319
- outputDir: constants_2.BUILD_DEFAULT_DIR,
346
+ outputDir: constants_2.CLIENT_OUTPUT_DIR,
320
347
  webpackHelpers: defaultWebpackHelpers
321
348
  });
322
349
  return [
323
350
  {
324
351
  chain: defaultChain,
325
- name: constants_1.BUNDLER_DEFAULT_TARGET
352
+ name: constants_1.BUNDLER_TARGET_CLIENT
326
353
  }
327
354
  ];
328
355
  }
@@ -336,7 +363,7 @@ class WebpackBundler {
336
363
  const extraTargets = (yield this._cliContext.pluginRunner.addExtraTarget({
337
364
  createConfig: this._createConfig.bind(this),
338
365
  mode: this._cliContext.mode,
339
- webpack: webpack_1.default
366
+ webpack: webpack_1.webpack
340
367
  })).filter(Boolean);
341
368
  buildTargets.push(...extraTargets);
342
369
  for (const buildTarget of buildTargets) {
@@ -346,18 +373,15 @@ class WebpackBundler {
346
373
  name,
347
374
  mode: this._cliContext.mode,
348
375
  helpers: defaultWebpackHelpers,
349
- webpack: webpack_1.default,
376
+ webpack: webpack_1.webpack,
350
377
  resolveWebpackModule(path) {
351
- if (!path.startsWith('webpack/')) {
352
- console.error('path need startWith "webpack/" to resolve webpack module');
353
- }
354
- return require(`${webpack_1.webpackResolveContext}${path}`);
378
+ return (0, webpack_1.resolveWebpackModule)(path);
355
379
  }
356
380
  });
357
381
  if (hasEntry(chain)) {
358
382
  const chainConfig = chain.toConfig();
359
- logger.debug(`${name} Config`);
360
- logger.debug((0, util_1.inspect)((_a = chainConfig.resolve) === null || _a === void 0 ? void 0 : _a.alias, { depth: 10 }));
383
+ logger_1.default.debug(`${name} Config`);
384
+ logger_1.default.debug((0, util_1.inspect)((_a = chainConfig.resolve) === null || _a === void 0 ? void 0 : _a.alias, { depth: 10 }));
361
385
  targets.push({ name, config: chainConfig });
362
386
  }
363
387
  }
@@ -368,7 +392,7 @@ class WebpackBundler {
368
392
  function getBundler(ctx) {
369
393
  return __awaiter(this, void 0, void 0, function* () {
370
394
  try {
371
- yield (0, typescript_1.setupTypeScript)(ctx.paths);
395
+ yield (0, typescript_1.setupTypeScript)(ctx.paths, ctx.mode === 'production');
372
396
  const options = Object.assign(Object.assign({}, defaultBundleOptions), { preBundle: ctx.config.experimental.preBundle, ignoreTypeScriptErrors: ctx.config.typescript.ignoreBuildErrors });
373
397
  if (ctx.mode !== 'development') {
374
398
  options.preBundle = false;
@@ -379,7 +403,7 @@ function getBundler(ctx) {
379
403
  }
380
404
  catch (err) {
381
405
  if ((0, error_1.isFatalError)(err)) {
382
- console.error(err.message);
406
+ logger_1.default.error(err.message);
383
407
  process.exit(1);
384
408
  }
385
409
  throw err;
@@ -14,7 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.createWebpackConfig = void 0;
15
15
  const config_1 = require("@shuvi/toolpack/lib/webpack/config");
16
16
  const typescript_1 = require("./typescript");
17
- const constants_1 = require("../constants");
17
+ const AppSourceRegexp = /([/\\]shuvi-app[/\\])|([/\\]\.shuvi[/\\])/;
18
18
  function createWebpackConfig({ mode, assetPublicPath, paths, config }, _a) {
19
19
  var { webpackHelpers } = _a, opts = __rest(_a, ["webpackHelpers"]);
20
20
  const dev = mode === 'development';
@@ -27,10 +27,15 @@ function createWebpackConfig({ mode, assetPublicPath, paths, config }, _a) {
27
27
  const cacheDir = paths.cacheDir;
28
28
  const publicPath = assetPublicPath;
29
29
  const env = config.env;
30
- const include = [paths.appDir, paths.srcDir, ...(opts.include || [])];
31
- const parcelCss = !!config.experimental.parcelCss;
30
+ const include = [
31
+ paths.srcDir,
32
+ paths.appDir,
33
+ AppSourceRegexp,
34
+ ...(opts.include || [])
35
+ ];
36
+ const lightningCss = !!config.experimental.lightningCss;
32
37
  const experimental = config.experimental;
33
- const compiler = config.compiler;
38
+ const compiler = Object.assign(Object.assign({}, config.compiler), { modularizeImports: experimental.modularizeImports, swcPlugins: experimental.swcPlugins });
34
39
  const typescript = (0, typescript_1.getTypeScriptInfo)();
35
40
  if (opts.node) {
36
41
  chain = (0, config_1.createNodeWebpackChain)({
@@ -40,14 +45,12 @@ function createWebpackConfig({ mode, assetPublicPath, paths, config }, _a) {
40
45
  outputDir,
41
46
  cacheDir,
42
47
  publicPath,
43
- parcelCss,
44
- experimental,
48
+ lightningCss,
45
49
  compiler,
46
50
  typescript,
47
51
  include,
48
52
  env,
49
- webpackHelpers,
50
- buildManifestFilename: constants_1.SERVER_BUILD_MANIFEST_PATH
53
+ webpackHelpers
51
54
  });
52
55
  }
53
56
  else {
@@ -58,17 +61,14 @@ function createWebpackConfig({ mode, assetPublicPath, paths, config }, _a) {
58
61
  outputDir,
59
62
  cacheDir,
60
63
  publicPath,
61
- parcelCss,
62
- experimental,
64
+ lightningCss,
63
65
  compiler,
64
66
  typescript,
65
67
  include,
66
68
  env,
67
69
  webpackHelpers,
68
- analyze: config.analyze,
69
- buildManifestFilename: constants_1.CLIENT_BUILD_MANIFEST_PATH
70
+ analyze: config.analyze
70
71
  });
71
- chain.optimization.runtimeChunk({ name: constants_1.BUILD_CLIENT_RUNTIME_WEBPACK });
72
72
  }
73
73
  chain.name(opts.name);
74
74
  chain.merge({
@@ -76,7 +76,7 @@ function createWebpackConfig({ mode, assetPublicPath, paths, config }, _a) {
76
76
  });
77
77
  chain.resolve.alias.set('@shuvi/app', paths.appDir);
78
78
  chain.resolve.alias.set('@shuvi/runtime', paths.runtimeDir);
79
- chain.resolve.alias.set('@shuvi/user', paths.srcDir);
79
+ chain.resolve.alias.set('@', paths.srcDir);
80
80
  return chain;
81
81
  }
82
82
  exports.createWebpackConfig = createWebpackConfig;
@@ -0,0 +1 @@
1
+ export declare function getOnline(): Promise<boolean>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getOnline = void 0;
7
+ const child_process_1 = require("child_process");
8
+ const dns_1 = __importDefault(require("dns"));
9
+ const url_1 = __importDefault(require("url"));
10
+ function getProxy() {
11
+ if (process.env.https_proxy) {
12
+ return process.env.https_proxy;
13
+ }
14
+ try {
15
+ const httpsProxy = (0, child_process_1.execSync)('npm config get https-proxy').toString().trim();
16
+ return httpsProxy !== 'null' ? httpsProxy : undefined;
17
+ }
18
+ catch (e) {
19
+ return;
20
+ }
21
+ }
22
+ function getOnline() {
23
+ return new Promise(resolve => {
24
+ dns_1.default.lookup('registry.yarnpkg.com', registryErr => {
25
+ if (!registryErr) {
26
+ return resolve(true);
27
+ }
28
+ const proxy = getProxy();
29
+ if (!proxy) {
30
+ return resolve(false);
31
+ }
32
+ const { hostname } = url_1.default.parse(proxy);
33
+ if (!hostname) {
34
+ return resolve(false);
35
+ }
36
+ dns_1.default.lookup(hostname, proxyErr => {
37
+ resolve(proxyErr == null);
38
+ });
39
+ });
40
+ });
41
+ }
42
+ exports.getOnline = getOnline;
@@ -1,5 +1,5 @@
1
1
  import { Compiler, MultiCompiler } from '@shuvi/toolpack/lib/webpack';
2
- import type webpack from '@shuvi/toolpack/lib/webpack';
2
+ import type { webpack } from '@shuvi/toolpack/lib/webpack';
3
3
  export declare type BundlerResult = {
4
4
  errors: webpack.StatsError[];
5
5
  warnings: webpack.StatsError[];
@@ -8,6 +8,6 @@ export declare type CheckedDependenciesResult = {
8
8
  missing: PackageDep[];
9
9
  };
10
10
  export declare function hasTypescriptFiles(projectDir: string): Promise<boolean>;
11
- export declare function checkNecessarytDeps(projectDir: string): CheckedDependenciesResult;
11
+ export declare function checkNecessaryDeps(projectDir: string): CheckedDependenciesResult;
12
12
  export declare function hasTsConfig(tsConfigPath: string): Promise<boolean>;
13
13
  export declare function getTsConfig(ts: TypeScriptModule, tsConfigPath: string): Promise<TsConfig>;
@@ -12,11 +12,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.getTsConfig = exports.hasTsConfig = exports.checkNecessarytDeps = exports.hasTypescriptFiles = void 0;
15
+ exports.getTsConfig = exports.hasTsConfig = exports.checkNecessaryDeps = exports.hasTypescriptFiles = void 0;
16
16
  const fs_extra_1 = require("fs-extra");
17
17
  const os_1 = __importDefault(require("os"));
18
18
  const path_1 = __importDefault(require("path"));
19
19
  const chalk_1 = __importDefault(require("@shuvi/utils/lib/chalk"));
20
+ const logger_1 = __importDefault(require("@shuvi/utils/lib/logger"));
20
21
  const resolve_1 = require("@shuvi/utils/lib/resolve");
21
22
  const recursiveReaddir_1 = require("@shuvi/utils/lib/recursiveReaddir");
22
23
  const requiredPackages = [
@@ -29,7 +30,7 @@ function checkDependencies(dir, deps) {
29
30
  let resolutions = new Map();
30
31
  const missingPackages = deps.filter(p => {
31
32
  try {
32
- resolutions.set(p.pkg, (0, resolve_1.resolve)(p.file, { basedir: `${dir}/` }));
33
+ resolutions.set(p.pkg, (0, resolve_1.resolve)(p.file, { basedir: dir }));
33
34
  return false;
34
35
  }
35
36
  catch (_) {
@@ -60,10 +61,10 @@ function hasTypescriptFiles(projectDir) {
60
61
  });
61
62
  }
62
63
  exports.hasTypescriptFiles = hasTypescriptFiles;
63
- function checkNecessarytDeps(projectDir) {
64
+ function checkNecessaryDeps(projectDir) {
64
65
  return checkDependencies(projectDir, requiredPackages);
65
66
  }
66
- exports.checkNecessarytDeps = checkNecessarytDeps;
67
+ exports.checkNecessaryDeps = checkNecessaryDeps;
67
68
  function hasTsConfig(tsConfigPath) {
68
69
  return __awaiter(this, void 0, void 0, function* () {
69
70
  const hasTsConfig = yield (0, fs_extra_1.pathExists)(tsConfigPath);
@@ -106,7 +107,7 @@ function getTsConfig(ts, tsConfigPath) {
106
107
  }
107
108
  catch (err) {
108
109
  if (err && err.name === 'SyntaxError') {
109
- console.error(chalk_1.default.red.bold('Could not parse', chalk_1.default.cyan('tsconfig.json') + '.', 'Please make sure it contains syntactically correct JSON.'));
110
+ logger_1.default.error('Could not parse', chalk_1.default.cyan('tsconfig.json') + '.', 'Please make sure it contains syntactically correct JSON.');
110
111
  }
111
112
  console.info((err === null || err === void 0 ? void 0 : err.message) ? `${err.message}` : '');
112
113
  throw err;
@@ -0,0 +1,26 @@
1
+ import { PackageManager } from '../helper/getPkgManager';
2
+ interface InstallArgs {
3
+ /**
4
+ * Indicate whether to install packages using npm, pnpm or Yarn.
5
+ */
6
+ packageManager: PackageManager;
7
+ /**
8
+ * Indicate whether there is an active Internet connection.
9
+ */
10
+ isOnline: boolean;
11
+ /**
12
+ * Indicate whether the given dependencies are devDependencies.
13
+ */
14
+ devDependencies?: boolean;
15
+ }
16
+ export declare type Dependencies = {
17
+ resolved: Map<string, string>;
18
+ };
19
+ /**
20
+ * Spawn a package manager installation with either Yarn or NPM.
21
+ *
22
+ * @returns A Promise that resolves once the installation is finished.
23
+ */
24
+ export declare function install(root: string, dependencies: string[] | null, { packageManager, isOnline, devDependencies }: InstallArgs): Promise<void>;
25
+ export declare function installDependencies(baseDir: string, deps: any, dev?: boolean): Promise<void>;
26
+ export {};
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.installDependencies = exports.install = void 0;
39
+ const chalk_1 = __importDefault(require("@shuvi/utils/lib/chalk"));
40
+ const cross_spawn_1 = __importDefault(require("cross-spawn"));
41
+ const path = __importStar(require("path"));
42
+ const getPkgManager_1 = require("../helper/getPkgManager");
43
+ const getOnline_1 = require("../helper/getOnline");
44
+ /**
45
+ * Spawn a package manager installation with either Yarn or NPM.
46
+ *
47
+ * @returns A Promise that resolves once the installation is finished.
48
+ */
49
+ function install(root, dependencies, { packageManager, isOnline, devDependencies }) {
50
+ /**
51
+ * (p)npm-specific command-line flags.
52
+ */
53
+ const npmFlags = [];
54
+ /**
55
+ * Yarn-specific command-line flags.
56
+ */
57
+ const yarnFlags = [];
58
+ /**
59
+ * Return a Promise that resolves once the installation is finished.
60
+ */
61
+ return new Promise((resolve, reject) => {
62
+ let args;
63
+ let command = packageManager;
64
+ const useYarn = packageManager === 'yarn';
65
+ if (dependencies && dependencies.length) {
66
+ /**
67
+ * If there are dependencies, run a variation of `{packageManager} add`.
68
+ */
69
+ if (useYarn) {
70
+ /**
71
+ * Call `yarn add --exact (--offline)? (-D)? ...`.
72
+ */
73
+ args = ['add', '--exact'];
74
+ if (!isOnline)
75
+ args.push('--offline');
76
+ args.push('--cwd', root);
77
+ if (devDependencies)
78
+ args.push('--dev');
79
+ args.push(...dependencies);
80
+ }
81
+ else {
82
+ /**
83
+ * Call `(p)npm install [--save|--save-dev] ...`.
84
+ */
85
+ args = ['install', '--save-exact'];
86
+ args.push(devDependencies ? '--save-dev' : '--save');
87
+ args.push(...dependencies);
88
+ }
89
+ }
90
+ else {
91
+ /**
92
+ * If there are no dependencies, run a variation of `{packageManager}
93
+ * install`.
94
+ */
95
+ args = ['install'];
96
+ if (!isOnline) {
97
+ console.log(chalk_1.default.yellow('You appear to be offline.'));
98
+ if (useYarn) {
99
+ console.log(chalk_1.default.yellow('Falling back to the local Yarn cache.'));
100
+ console.log();
101
+ args.push('--offline');
102
+ }
103
+ else {
104
+ console.log();
105
+ }
106
+ }
107
+ }
108
+ /**
109
+ * Add any package manager-specific flags.
110
+ */
111
+ if (useYarn) {
112
+ args.push(...yarnFlags);
113
+ }
114
+ else {
115
+ args.push(...npmFlags);
116
+ }
117
+ /**
118
+ * Spawn the installation process.
119
+ */
120
+ const child = (0, cross_spawn_1.default)(command, args, {
121
+ stdio: 'inherit',
122
+ env: Object.assign(Object.assign({}, process.env), { ADBLOCK: '1',
123
+ // we set NODE_ENV to development as pnpm skips dev
124
+ // dependencies when production
125
+ NODE_ENV: 'development', DISABLE_OPENCOLLECTIVE: '1' })
126
+ });
127
+ child.on('close', code => {
128
+ if (code !== 0) {
129
+ reject({ command: `${command} ${args.join(' ')}` });
130
+ return;
131
+ }
132
+ resolve();
133
+ });
134
+ });
135
+ }
136
+ exports.install = install;
137
+ function installDependencies(baseDir, deps, dev = false) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ const packageManager = (0, getPkgManager_1.getPkgManager)(baseDir);
140
+ const isOnline = yield (0, getOnline_1.getOnline)();
141
+ if (deps.length) {
142
+ console.log();
143
+ console.log(`Installing ${dev ? 'devDependencies' : 'dependencies'} (${packageManager}):`);
144
+ for (const dep of deps) {
145
+ console.log(`- ${chalk_1.default.cyan(dep.pkg)}`);
146
+ }
147
+ console.log();
148
+ yield install(path.resolve(baseDir), deps.map((dep) => dep.pkg), { devDependencies: dev, isOnline, packageManager });
149
+ console.log();
150
+ }
151
+ });
152
+ }
153
+ exports.installDependencies = installDependencies;
@@ -8,5 +8,5 @@ interface TypeScriptInfo {
8
8
  resolvedBaseUrl?: string;
9
9
  }
10
10
  export declare function getTypeScriptInfo(): TypeScriptInfo;
11
- export declare function setupTypeScript(paths: IPaths): Promise<void>;
11
+ export declare function setupTypeScript(paths: IPaths, reportMissingError?: Boolean): Promise<void>;
12
12
  export {};
@@ -43,6 +43,7 @@ const error_1 = require("../../error");
43
43
  const getPkgManager_1 = require("../helper/getPkgManager");
44
44
  const configTypeScript_1 = require("./configTypeScript");
45
45
  const getTypeScriptInfo_1 = require("./getTypeScriptInfo");
46
+ const installDependencies_1 = require("./installDependencies");
46
47
  let hasSetup = false;
47
48
  let useTypeScript;
48
49
  let typeScriptPath;
@@ -64,7 +65,7 @@ function missingPackagesError(dir, pkgs) {
64
65
  const removalMsg = '\n\n' +
65
66
  chalk_1.default.bold('If you are not trying to use TypeScript, please remove the ' +
66
67
  chalk_1.default.cyan('tsconfig.json') +
67
- ' file from your package root (and any TypeScript files in your pages directory).');
68
+ ' file from your package root (and any TypeScript files in your routes directory).');
68
69
  throw error_1.Error.Fatal(chalk_1.default.bold.red(`It looks like you're trying to use TypeScript but do not have the required package(s) installed.`) +
69
70
  '\n\n' +
70
71
  chalk_1.default.bold(`Please install ${chalk_1.default.bold(packagesHuman)} by running:`) +
@@ -92,7 +93,7 @@ function getTypeScriptInfo() {
92
93
  };
93
94
  }
94
95
  exports.getTypeScriptInfo = getTypeScriptInfo;
95
- function setupTypeScript(paths) {
96
+ function setupTypeScript(paths, reportMissingError = false) {
96
97
  return __awaiter(this, void 0, void 0, function* () {
97
98
  if (hasSetup) {
98
99
  return;
@@ -102,9 +103,28 @@ function setupTypeScript(paths) {
102
103
  useTypeScript = yield (0, getTypeScriptInfo_1.hasTypescriptFiles)(paths.srcDir);
103
104
  tsCompilerOptions = {};
104
105
  if (useTypeScript) {
105
- const deps = (0, getTypeScriptInfo_1.checkNecessarytDeps)(projectDir);
106
+ let deps = (0, getTypeScriptInfo_1.checkNecessaryDeps)(projectDir);
106
107
  if (deps.missing.length > 0) {
107
- missingPackagesError(projectDir, deps.missing);
108
+ if (reportMissingError) {
109
+ missingPackagesError(projectDir, deps.missing);
110
+ }
111
+ console.log(chalk_1.default.bold.yellow(`It looks like you're trying to use TypeScript but do not have the required package(s) installed.`) +
112
+ '\n' +
113
+ 'Installing dependencies' +
114
+ '\n\n' +
115
+ chalk_1.default.bold('If you are not trying to use TypeScript, please remove the ' +
116
+ chalk_1.default.cyan('tsconfig.json') +
117
+ ' file from your package root (and any TypeScript files in your pages directory).') +
118
+ '\n');
119
+ yield (0, installDependencies_1.installDependencies)(paths.srcDir, deps.missing, true).catch(err => {
120
+ if (err && typeof err === 'object' && 'command' in err) {
121
+ console.error(`Failed to install required TypeScript dependencies, please install them manually to continue:\n` +
122
+ err.command +
123
+ '\n');
124
+ }
125
+ throw err;
126
+ });
127
+ deps = (0, getTypeScriptInfo_1.checkNecessaryDeps)(projectDir);
108
128
  }
109
129
  typeScriptPath = deps.resovled.get('typescript');
110
130
  tsConfigPath = path.join(projectDir, 'tsconfig.json');
@@ -114,8 +134,7 @@ function setupTypeScript(paths) {
114
134
  console.log();
115
135
  yield fs_extra_1.default.writeJson(tsConfigPath, {});
116
136
  }
117
- // @ts-ignore
118
- const { default: ts } = (yield import(typeScriptPath));
137
+ const ts = require(typeScriptPath);
119
138
  const tsConfig = yield (0, getTypeScriptInfo_1.getTsConfig)(ts, tsConfigPath);
120
139
  tsCompilerOptions = tsConfig.options;
121
140
  yield (0, configTypeScript_1.writeDefaultConfigurations)(ts, tsConfigPath, tsConfig, paths, needDefaultTsConfig);