@umijs/preset-umi 4.0.0-beta.10 → 4.0.0-beta.14

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.
@@ -24,11 +24,15 @@ window.__vite_plugin_react_preamble_installed__ = true
24
24
  function createRouteMiddleware(opts) {
25
25
  return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
26
26
  const { vite } = opts.api.args;
27
+ const viteScripts = [
28
+ // add noshim attr for skip importmap shim logic for this modules
29
+ { content: viteRefreshScript, noshim: '' },
30
+ { src: '/@vite/client', noshim: '' },
31
+ '/.umi/umi.ts',
32
+ ];
27
33
  const markupArgs = yield (0, getMarkupArgs_1.getMarkupArgs)(opts);
28
34
  // @ts-ignore
29
- const requestHandler = yield (0, server_1.createRequestHandler)(Object.assign(Object.assign({}, markupArgs), { scripts: (vite
30
- ? [viteRefreshScript, '/@vite/client', '/.umi/umi.ts']
31
- : ['/umi.js']).concat(markupArgs.scripts), esmScript: vite }));
35
+ const requestHandler = yield (0, server_1.createRequestHandler)(Object.assign(Object.assign({}, markupArgs), { scripts: (vite ? viteScripts : ['/umi.js']).concat(markupArgs.scripts), esmScript: vite }));
32
36
  requestHandler(req, res, next);
33
37
  });
34
38
  }
@@ -230,7 +230,10 @@ PORT=8888 umi dev
230
230
  : { babelPreset, chainWebpack, modifyWebpackConfig })), { beforeBabelPlugins,
231
231
  beforeBabelPresets,
232
232
  extraBabelPlugins,
233
- extraBabelPresets, beforeMiddlewares: [faviconMiddleware_1.faviconMiddleware].concat(beforeMiddlewares), afterMiddlewares: [(0, createRouteMiddleware_1.createRouteMiddleware)({ api })].concat(middlewares), onDevCompileDone(opts) {
233
+ extraBabelPresets, beforeMiddlewares: [].concat([
234
+ ...beforeMiddlewares,
235
+ faviconMiddleware_1.faviconMiddleware,
236
+ ]), afterMiddlewares: [(0, createRouteMiddleware_1.createRouteMiddleware)({ api })].concat(middlewares), onDevCompileDone(opts) {
234
237
  api.applyPlugins({
235
238
  key: 'onDevCompileDone',
236
239
  args: opts,
@@ -2,6 +2,8 @@ import { IApi } from '../../types';
2
2
  export declare function getMarkupArgs(opts: {
3
3
  api: IApi;
4
4
  }): Promise<{
5
+ mountElementId: any;
6
+ base: any;
5
7
  routes: any;
6
8
  favicon: any;
7
9
  headScripts: any;
@@ -41,6 +41,8 @@ function getMarkupArgs(opts) {
41
41
  initialValue: opts.api.config.favicon,
42
42
  });
43
43
  return {
44
+ mountElementId: opts.api.config.mountElementId,
45
+ base: opts.api.config.base,
44
46
  routes: opts.api.appData.routes,
45
47
  favicon,
46
48
  headScripts,
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  const utils_1 = require("@umijs/utils");
4
13
  exports.default = (api) => {
@@ -6,14 +15,16 @@ exports.default = (api) => {
6
15
  name: 'setup',
7
16
  description: 'setup project',
8
17
  fn() {
9
- // generate tmp files
10
- utils_1.logger.info('generate files');
11
- api.applyPlugins({
12
- key: 'onGenerateFiles',
13
- args: {
14
- files: null,
15
- isFirstTime: false,
16
- },
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ // generate tmp files
20
+ utils_1.logger.info('generate files');
21
+ yield api.applyPlugins({
22
+ key: 'onGenerateFiles',
23
+ args: {
24
+ files: null,
25
+ isFirstTime: false,
26
+ },
27
+ });
17
28
  });
18
29
  },
19
30
  });
@@ -9,8 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ const bundler_utils_1 = require("@umijs/bundler-utils");
12
13
  const utils_1 = require("@umijs/utils");
14
+ const fs_1 = require("fs");
13
15
  const path_1 = require("path");
16
+ const watch_1 = require("../../commands/dev/watch");
14
17
  const routes_1 = require("../tmpFiles/routes");
15
18
  exports.default = (api) => {
16
19
  api.modifyAppData((memo) => __awaiter(void 0, void 0, void 0, function* () {
@@ -25,6 +28,36 @@ exports.default = (api) => {
25
28
  memo.react = {
26
29
  version: require((0, path_1.join)(api.config.alias.react, 'package.json')).version,
27
30
  };
31
+ memo.appJS = yield getAppJsInfo();
28
32
  return memo;
29
33
  }));
34
+ // Execute earliest, so that other onGenerateFiles can get it
35
+ api.register({
36
+ key: 'onGenerateFiles',
37
+ fn(args) {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ if (!args.isFirstTime) {
40
+ api.appData.appJS = yield getAppJsInfo();
41
+ }
42
+ });
43
+ },
44
+ stage: Number.NEGATIVE_INFINITY,
45
+ });
46
+ function getAppJsInfo() {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ for (const path of (0, watch_1.expandJSPaths)((0, path_1.join)(api.paths.absSrcPath, 'app'))) {
49
+ if ((0, fs_1.existsSync)(path)) {
50
+ const [_, exports] = yield (0, bundler_utils_1.parseModule)({
51
+ path,
52
+ content: (0, fs_1.readFileSync)(path, 'utf-8'),
53
+ });
54
+ return {
55
+ path,
56
+ exports,
57
+ };
58
+ }
59
+ }
60
+ return null;
61
+ });
62
+ }
30
63
  };
@@ -31,4 +31,15 @@ exports.default = (api) => {
31
31
  },
32
32
  });
33
33
  }));
34
+ api.onCheckCode((args) => {
35
+ // Fixed version import is not allowed
36
+ // e.g. import { X } from '_@ant-design_icons@4.7.0@ant-design/icons'
37
+ if (['cnpm', 'tnpm'].includes(api.appData.npmClient)) {
38
+ args.imports.forEach(({ source }) => {
39
+ if (/@\d/.test(source)) {
40
+ throw new Error(`${source} is not allowed to import.`);
41
+ }
42
+ });
43
+ }
44
+ });
34
45
  };
@@ -8,7 +8,7 @@ function resolveProjectDep(opts) {
8
8
  var _a, _b;
9
9
  if (((_a = opts.pkg.dependencies) === null || _a === void 0 ? void 0 : _a[opts.dep]) ||
10
10
  ((_b = opts.pkg.devDependencies) === null || _b === void 0 ? void 0 : _b[opts.dep])) {
11
- return (0, path_1.dirname)(utils_1.resolve.sync(`${opts.dep}/package`, {
11
+ return (0, path_1.dirname)(utils_1.resolve.sync(`${opts.dep}/package.json`, {
12
12
  basedir: opts.cwd,
13
13
  }));
14
14
  }
@@ -34,6 +34,8 @@ exports.default = (api) => {
34
34
  externals: {},
35
35
  autoCSSModules: true,
36
36
  publicPath: '/',
37
+ mountElementId: 'root',
38
+ base: '/',
37
39
  };
38
40
  const bundleSchemas = (0, schema_1.getSchemas)();
39
41
  const extraSchemas = (0, schema_2.getSchemas)();
@@ -55,7 +57,9 @@ exports.default = (api) => {
55
57
  }
56
58
  // api.paths is ready after register
57
59
  api.modifyConfig((memo, args) => {
58
- memo.alias = Object.assign(Object.assign({}, memo.alias), { '@': args.paths.absSrcPath, '@@': args.paths.absTmpPath });
60
+ memo.alias = Object.assign(Object.assign({}, memo.alias), { '@': args.paths.absSrcPath, '@@': args.paths.absTmpPath,
61
+ // like vite, use to pre-bundling dependencies in vite mode
62
+ '@fs': '/' });
59
63
  return memo;
60
64
  });
61
65
  };
@@ -4,11 +4,13 @@ exports.getSchemas = void 0;
4
4
  const utils_1 = require("@umijs/utils");
5
5
  function getSchemas() {
6
6
  return {
7
+ base: (Joi) => Joi.string(),
7
8
  plugins: (Joi) => Joi.array().items(Joi.string()),
8
9
  publicPath: (Joi) => Joi.string().regex(/\/$/).error(new Error('publicPath must end with /')),
9
10
  favicon: (Joi) => Joi.string(),
10
11
  headScripts: (Joi) => Joi.array().items(Joi.alternatives(Joi.string())),
11
12
  scripts: (Joi) => Joi.array().items(Joi.alternatives(Joi.string())),
13
+ mountElementId: (Joi) => Joi.string(),
12
14
  npmClient: (Joi) => Joi.string().valid(utils_1.NpmClientEnum.pnpm, utils_1.NpmClientEnum.tnpm, utils_1.NpmClientEnum.cnpm, utils_1.NpmClientEnum.yarn, utils_1.NpmClientEnum.npm),
13
15
  routes: (Joi) => Joi.array().items(Joi.object()),
14
16
  };
@@ -0,0 +1,75 @@
1
+ import type { IApi } from '../../types';
2
+ export interface IImportmapData {
3
+ importMap: {
4
+ imports: Record<string, string>;
5
+ scopes: Record<string, any>;
6
+ };
7
+ deps: {
8
+ name: string;
9
+ version: string;
10
+ type: string;
11
+ }[];
12
+ }
13
+ export interface IPkgData {
14
+ pkgJsonContent: IApi['pkg'];
15
+ pkgInfo: {
16
+ name: string;
17
+ version: string;
18
+ type: 'esm';
19
+ exports: {
20
+ name: string;
21
+ path: string;
22
+ from: string;
23
+ deps: {
24
+ name: string;
25
+ version: string;
26
+ usedMap: Record<string, {
27
+ usedNamespace?: boolean;
28
+ usedDefault?: boolean;
29
+ usedNames: string[];
30
+ }>;
31
+ }[];
32
+ }[];
33
+ assets: any[];
34
+ };
35
+ }
36
+ /**
37
+ * class for connect esmi server
38
+ */
39
+ export default class ESMIService {
40
+ cdnOrigin: string;
41
+ cacheDir: string;
42
+ cache: Record<string, IImportmapData>;
43
+ constructor(opts: {
44
+ cdnOrigin: string;
45
+ cacheDir: string;
46
+ });
47
+ /**
48
+ * get cache file path by cache key
49
+ * @param data pkg data
50
+ */
51
+ static getCacheKey(data: IPkgData): string;
52
+ /**
53
+ * get importmap cache by cache key
54
+ * @param key cache key
55
+ */
56
+ getCache(key: string): IImportmapData;
57
+ /**
58
+ * set importmap cache
59
+ * @param key cache key
60
+ * @param data importmap data
61
+ */
62
+ setCache(key: string, data: IImportmapData): void;
63
+ /**
64
+ * build importmap from deps tree
65
+ * @param data package data
66
+ * @returns ticketId
67
+ */
68
+ build(data: IPkgData): Promise<string | undefined>;
69
+ /**
70
+ * get importmap from deps tree
71
+ * @param data package data
72
+ * @returns importmap
73
+ */
74
+ getImportmap(data: IPkgData): Promise<IImportmapData | undefined>;
75
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const utils_1 = require("@umijs/utils");
16
+ const crypto_1 = require("crypto");
17
+ const fs_1 = __importDefault(require("fs"));
18
+ const path_1 = __importDefault(require("path"));
19
+ /**
20
+ * class for connect esmi server
21
+ */
22
+ class ESMIService {
23
+ constructor(opts) {
24
+ this.cdnOrigin = '';
25
+ this.cacheDir = '';
26
+ this.cache = {};
27
+ this.cdnOrigin = opts.cdnOrigin;
28
+ this.cacheDir = opts.cacheDir;
29
+ // restore local cache
30
+ const cacheFilePath = path_1.default.join(this.cacheDir, 'importmap.json');
31
+ if (fs_1.default.existsSync(cacheFilePath)) {
32
+ try {
33
+ this.cache = require(cacheFilePath);
34
+ }
35
+ catch (_a) {
36
+ /* nothing */
37
+ }
38
+ }
39
+ }
40
+ /**
41
+ * get cache file path by cache key
42
+ * @param data pkg data
43
+ */
44
+ static getCacheKey(data) {
45
+ const hash = (0, crypto_1.createHash)('md4');
46
+ hash.update(JSON.stringify(data.pkgInfo.exports));
47
+ return hash.digest('hex');
48
+ }
49
+ /**
50
+ * get importmap cache by cache key
51
+ * @param key cache key
52
+ */
53
+ getCache(key) {
54
+ return this.cache[key];
55
+ }
56
+ /**
57
+ * set importmap cache
58
+ * @param key cache key
59
+ * @param data importmap data
60
+ */
61
+ setCache(key, data) {
62
+ this.cache[key] = data;
63
+ // create cache dir
64
+ if (!fs_1.default.existsSync(this.cacheDir)) {
65
+ fs_1.default.mkdirSync(this.cacheDir, { recursive: true });
66
+ }
67
+ // write cache to file system
68
+ fs_1.default.writeFileSync(path_1.default.join(this.cacheDir, 'importmap.json'), JSON.stringify(this.cache, null, 2));
69
+ }
70
+ /**
71
+ * build importmap from deps tree
72
+ * @param data package data
73
+ * @returns ticketId
74
+ */
75
+ build(data) {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ return utils_1.axios
78
+ .post(`${this.cdnOrigin}/api/v1/esm/build`, data)
79
+ .then((a) => { var _a; return (_a = a.data.data) === null || _a === void 0 ? void 0 : _a.ticketId; });
80
+ });
81
+ }
82
+ /**
83
+ * get importmap from deps tree
84
+ * @param data package data
85
+ * @returns importmap
86
+ */
87
+ getImportmap(data) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ const cacheKey = ESMIService.getCacheKey(data);
90
+ const cache = this.getCache(cacheKey);
91
+ const stamp = +new Date();
92
+ // use valid cache first
93
+ if (cache) {
94
+ utils_1.logger.info('ESMi cache used');
95
+ return cache;
96
+ }
97
+ // log dependency list
98
+ utils_1.logger.info(utils_1.chalk.greenBright('Pre-compiling dependencies on esmi:'));
99
+ data.pkgInfo.exports[0].deps.forEach((dep) => {
100
+ console.log(utils_1.chalk.yellow(` ${dep.name}`));
101
+ });
102
+ // get the build ticket id
103
+ const ticketId = yield this.build(data);
104
+ // continue to the next request after 2s
105
+ const next = () => new Promise((resolve) => setTimeout(() => resolve(deferrer()), 2000));
106
+ const deferrer = () => {
107
+ return utils_1.axios
108
+ .get(`${this.cdnOrigin}/api/v1/esm/importmap/${ticketId}`)
109
+ .then((res) => {
110
+ if (res.data.success) {
111
+ this.setCache(cacheKey, res.data.data);
112
+ utils_1.logger.info(`Done, took ${((+new Date() - stamp) / 1000).toFixed(1)}s`);
113
+ return res.data.data;
114
+ }
115
+ return next();
116
+ }, next);
117
+ };
118
+ return deferrer();
119
+ });
120
+ }
121
+ }
122
+ exports.default = ESMIService;
@@ -1,3 +1,3 @@
1
- import { IApi } from '../../types';
1
+ import type { IApi } from '../../types';
2
2
  declare const _default: (api: IApi) => void;
3
3
  export default _default;
@@ -8,37 +8,197 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
+ const es_module_lexer_1 = require("@umijs/bundler-utils/compiled/es-module-lexer");
16
+ const magic_string_1 = __importDefault(require("magic-string"));
12
17
  const path_1 = require("path");
13
18
  const scan_1 = require("../../libs/scan");
19
+ const Service_1 = __importDefault(require("./Service"));
20
+ let importmap = { imports: {}, scopes: {} };
21
+ /**
22
+ * esmi vite plugin
23
+ */
24
+ function esmi(opts) {
25
+ return {
26
+ name: 'preset-umi:esmi',
27
+ configResolved(config) {
28
+ const { include, exclude } = config.optimizeDeps;
29
+ // do not pre-compile deps which will be loaded by importmap (for top-level deps)
30
+ if (include === null || include === void 0 ? void 0 : include.length) {
31
+ config.optimizeDeps.include = include.filter((item) => !importmap.imports[item]);
32
+ }
33
+ // exclude pre-compile deps which within importmap by default (for nested deps)
34
+ config.optimizeDeps.exclude = (exclude || []).concat(Object.keys(importmap.imports).filter((item) => exclude === null || exclude === void 0 ? void 0 : exclude.includes(item)));
35
+ },
36
+ transform(source) {
37
+ try {
38
+ // parse imports
39
+ const imports = (0, es_module_lexer_1.parse)(source)[0];
40
+ let s;
41
+ // process all imports
42
+ imports.forEach((item) => {
43
+ const { n: specifier, s: start, e: end } = item;
44
+ // replace npm package to CDN url for matched imports
45
+ if (specifier && importmap.imports[specifier]) {
46
+ s !== null && s !== void 0 ? s : (s = new magic_string_1.default(source));
47
+ s.overwrite(start, end, importmap.imports[specifier]);
48
+ }
49
+ });
50
+ return (s === null || s === void 0 ? void 0 : s.toString()) || source;
51
+ }
52
+ catch (_a) {
53
+ // syntax error or non-javascript files
54
+ return null;
55
+ }
56
+ },
57
+ handleHotUpdate(ctx) {
58
+ return opts.handleHotUpdate(ctx);
59
+ },
60
+ };
61
+ }
62
+ /**
63
+ * generate package data
64
+ * @param api plugin api
65
+ */
66
+ function generatePkgData(api) {
67
+ return {
68
+ pkgJsonContent: {
69
+ dependencies: api.pkg.dependencies || {},
70
+ devDependencies: api.pkg.devDependencies || {},
71
+ },
72
+ pkgInfo: {
73
+ name: api.pkg.name,
74
+ version: api.pkg.version,
75
+ type: 'esm',
76
+ exports: [
77
+ {
78
+ name: 'default',
79
+ path: 'es/index.js',
80
+ from: '',
81
+ deps: Object.entries(api.appData.deps).map(([name, version]) => ({
82
+ name,
83
+ version,
84
+ usedMap: {
85
+ [name]: { usedNamespace: true, usedNames: [] },
86
+ },
87
+ })),
88
+ },
89
+ ],
90
+ assets: [],
91
+ },
92
+ };
93
+ }
14
94
  exports.default = (api) => {
95
+ let service;
96
+ let resolver;
97
+ /**
98
+ * refresh importmap and save to the top-level variable
99
+ */
100
+ function refreshImportMap() {
101
+ var _a;
102
+ return __awaiter(this, void 0, void 0, function* () {
103
+ // scan and module graph
104
+ // TODO: module graph
105
+ api.appData.deps = yield (0, scan_1.scan)({
106
+ entry: (0, path_1.join)(api.paths.absTmpPath, 'umi.ts'),
107
+ externals: api.config.externals,
108
+ resolver,
109
+ });
110
+ // skip umi by default
111
+ delete api.appData.deps['umi'];
112
+ // FIXME: force include react & react-dom
113
+ api.appData.deps['react'] = api.appData.react.version;
114
+ api.appData.deps['react-dom'] = api.appData.react.version;
115
+ const data = generatePkgData(api);
116
+ const deps = data.pkgInfo.exports.reduce((r, exp) => r.concat(exp.deps.map((dep) => dep.name)), []);
117
+ const hasNewDep = deps.some((i) => !importmap.imports[i]);
118
+ // update importmap from esm if there has new import
119
+ if (hasNewDep) {
120
+ // TODO: add local cache and restore
121
+ importmap = (_a = (yield service.getImportmap(data))) === null || _a === void 0 ? void 0 : _a.importMap;
122
+ // because we will replaced package name to CDN url in vite plugin
123
+ // so we must append scope rules for the CDN url like the import specifier
124
+ // example:
125
+ // origin:
126
+ // { imports: { a: 'aa', b: 'bb', c: 'cc1' }, scopes: { b: { c: 'cc2' } } }
127
+ // to:
128
+ // { imports: { a: 'aa', b: 'bb', c: 'cc1' }, scopes: { b: { c: 'cc2' }, 'bb': { c: 'cc2' } } }
129
+ Object.keys(importmap.scopes || {})
130
+ .filter((item) => importmap.imports[item])
131
+ .forEach((item) => {
132
+ importmap.scopes[importmap.imports[item]] = importmap.scopes[item];
133
+ });
134
+ }
135
+ });
136
+ }
137
+ // describe config
15
138
  api.describe({
16
139
  key: 'esmi',
17
140
  config: {
18
141
  schema(Joi) {
19
- return Joi.object();
142
+ return Joi.object({
143
+ cdnOrigin: Joi.string(),
144
+ shimUrl: Joi.string(),
145
+ });
20
146
  },
21
147
  },
22
148
  enableBy: api.EnableBy.config,
23
149
  });
150
+ // check bundler type
24
151
  api.onStart(() => {
25
152
  if (!api.args.vite) {
26
153
  throw new Error(`esmi can only be used in vite mode.`);
27
154
  }
28
155
  });
29
- // 需要在 generate 之后是因为需要先等临时文件生成
156
+ // collect all imports after tmp files generated
30
157
  api.onBeforeCompiler(() => __awaiter(void 0, void 0, void 0, function* () {
31
- // scan and module graph
32
- // TODO: module graph
33
158
  if (api.args.vite) {
34
- const resolver = (0, scan_1.createResolver)({
35
- alias: api.config.alias,
159
+ // init esmi service
160
+ service = new Service_1.default({
161
+ cdnOrigin: api.config.esmi.cdnOrigin,
162
+ cacheDir: (0, path_1.join)(api.cwd, '.esmi'),
36
163
  });
37
- api.appData.deps = yield (0, scan_1.scan)({
38
- entry: (0, path_1.join)(api.paths.absTmpPath, 'umi.ts'),
39
- externals: api.config.externals,
40
- resolver,
164
+ // init project resolver
165
+ resolver = (0, scan_1.createResolver)({
166
+ alias: api.config.alias,
41
167
  });
168
+ // init importmap
169
+ yield refreshImportMap();
42
170
  }
43
171
  }));
172
+ // append ipmortmap script for HTML
173
+ api.modifyHTML(($) => {
174
+ const scp = $('<script type="importmap"></script>\n');
175
+ scp.html(JSON.stringify(importmap, null, 2));
176
+ $('head > script:eq(0)').before(scp);
177
+ // append importmap shim script
178
+ if (api.config.esmi.shimUrl) {
179
+ $('body > script:eq(0)').before($(`<script src="${api.config.esmi.shimUrl}"></script>\n`));
180
+ }
181
+ // preload for importmap modules
182
+ Object.values(importmap.imports).forEach((url) => {
183
+ scp.before($(`<link rel="modulepreload" href="${url}" />\n`));
184
+ });
185
+ return $;
186
+ });
187
+ if (api.args.vite) {
188
+ // apply esmi vite plugin
189
+ api.modifyViteConfig((memo) => {
190
+ memo.plugins = (memo.plugins || []).concat(esmi({
191
+ handleHotUpdate: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
192
+ ctx.file;
193
+ // TODO: incremental refresh by ctx.file
194
+ yield refreshImportMap();
195
+ // TODO: refresh page when importmap changed
196
+ }),
197
+ }));
198
+ return memo;
199
+ });
200
+ }
201
+ else {
202
+ // TODO: webpack implementation
203
+ }
44
204
  };
@@ -34,7 +34,7 @@ exports.default = (api) => {
34
34
  }
35
35
  return memo;
36
36
  }));
37
- api.addMiddlewares(() => [
37
+ api.addBeforeMiddlewares(() => [
38
38
  (req, res, next) => {
39
39
  if (api.appData.faviconFile &&
40
40
  req.path === `/${api.appData.faviconFile}`) {
@@ -53,6 +53,8 @@ exports.default = (api) => {
53
53
  }
54
54
  });
55
55
  api.modifyHTMLFavicon((memo) => {
56
- return `${api.config.publicPath}${api.appData.faviconFile}` || memo;
56
+ return api.appData.faviconFile
57
+ ? `${api.config.publicPath}${api.appData.faviconFile}`
58
+ : memo;
57
59
  });
58
60
  };
@@ -3,11 +3,13 @@ import * as t from '@umijs/bundler-utils/compiled/babel/types';
3
3
  import { IOpts } from './lowImport';
4
4
  interface IPluginOpts {
5
5
  opts: IOpts;
6
+ css: string;
6
7
  }
7
8
  export default function (): {
8
9
  visitor: {
9
10
  Identifier(path: Babel.NodePath<t.Identifier>, state: {
10
11
  opts: IPluginOpts;
12
+ file: any;
11
13
  }): void;
12
14
  MemberExpression(path: Babel.NodePath<t.MemberExpression>, state: {
13
15
  opts: IPluginOpts;
@@ -21,11 +21,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
22
  const helper_module_imports_1 = require("@umijs/bundler-utils/compiled/babel/helper-module-imports");
23
23
  const t = __importStar(require("@umijs/bundler-utils/compiled/babel/types"));
24
+ const path_1 = require("path");
24
25
  function default_1() {
25
26
  return {
26
27
  visitor: {
27
28
  Identifier(path, state) {
28
- var _a, _b;
29
+ var _a, _b, _c;
29
30
  const { name } = path.node;
30
31
  if (path.scope.hasBinding(path.node.name)) {
31
32
  return;
@@ -44,7 +45,15 @@ function default_1() {
44
45
  nameHint: name,
45
46
  }));
46
47
  }
47
- // TODO: state.opts.opts.namespaceToLib
48
+ else if ((_c = state.opts.opts.namespaceToLib) === null || _c === void 0 ? void 0 : _c[name]) {
49
+ path.replaceWith((0, helper_module_imports_1.addNamespace)(path, state.opts.opts.namespaceToLib[name]));
50
+ }
51
+ // import css
52
+ if (name === 'styles' && state.opts.css) {
53
+ const { filename } = state.file.opts;
54
+ const cssFilename = (0, path_1.basename)(filename, (0, path_1.extname)(filename)) + '.' + state.opts.css;
55
+ path.replaceWith((0, helper_module_imports_1.addDefault)(path, './' + cssFilename, { nameHint: name }));
56
+ }
48
57
  },
49
58
  MemberExpression(path, state) {
50
59
  const { object, property } = path.node;
@@ -25,6 +25,7 @@ exports.default = (api) => {
25
25
  schema(Joi) {
26
26
  return Joi.object({
27
27
  libs: Joi.array(),
28
+ css: Joi.string(),
28
29
  });
29
30
  },
30
31
  },
@@ -46,7 +47,7 @@ exports.default = (api) => {
46
47
  const memberDts = (lib.members || [])
47
48
  .map((member) => `${member}: typeof import('${lib.importFrom}')['${member}'],`)
48
49
  .join('\n');
49
- return `const ${lib.withObj} = {\n${memberDts}\n};`;
50
+ return `const ${lib.withObj} : {\n${memberDts}\n};`;
50
51
  }
51
52
  else if (lib.namespaceImport) {
52
53
  return `const ${lib.namespaceImport}: typeof import('${lib.importFrom}');`;
@@ -60,20 +61,24 @@ exports.default = (api) => {
60
61
  .join('\n');
61
62
  }
62
63
  });
64
+ // TODO: styles 的类型提示
63
65
  const content = `
64
66
  // generated by umi
65
67
  declare global {
66
- ${dts}
68
+ ${dts.join('\n')}
69
+ const styles: any;
67
70
  }
68
71
  export {}
69
72
  `.trim() + `\n`;
70
73
  (0, fs_1.writeFileSync)((0, path_1.join)(api.paths.cwd, 'lowImport.d.ts'), content, 'utf-8');
71
74
  });
72
75
  api.addBeforeBabelPresets(() => {
76
+ var _a;
73
77
  const opts = normalizeLibs(api.appData.lowImport);
78
+ const css = ((_a = api.config.lowImport) === null || _a === void 0 ? void 0 : _a.css) || 'less';
74
79
  return [
75
80
  {
76
- plugins: [[babelPlugin_1.default, { opts }]],
81
+ plugins: [[babelPlugin_1.default, { opts, css }]],
77
82
  },
78
83
  ];
79
84
  });
@@ -24,6 +24,9 @@ function default_1(api) {
24
24
  });
25
25
  },
26
26
  },
27
+ enableBy() {
28
+ return api.name === 'dev';
29
+ },
27
30
  });
28
31
  // context for update mockData
29
32
  const context = {
@@ -51,6 +51,10 @@ function getRoutes(opts) {
51
51
  routes,
52
52
  });
53
53
  }
54
+ routes = yield opts.api.applyPlugins({
55
+ key: 'modifyRoutes',
56
+ initialValue: routes,
57
+ });
54
58
  return routes;
55
59
  });
56
60
  }
@@ -62,6 +66,12 @@ function getRouteComponents(opts) {
62
66
  const route = opts.routes[key];
63
67
  if (!route.file)
64
68
  return `// ${key}: no file to import`;
69
+ // e.g.
70
+ // component: () => <h1>foo</h1>
71
+ // component: (() => () => <h1>foo</h1>)()
72
+ if (route.file.startsWith('(')) {
73
+ return `'${key}': () => Promise.resolve(${route.file}),`;
74
+ }
65
75
  const path = (0, path_1.isAbsolute)(route.file) || route.file.startsWith('@/')
66
76
  ? route.file
67
77
  : `${opts.prefix}${route.file}`;
@@ -27,9 +27,11 @@ exports.default = (api) => {
27
27
  api.onGenerateFiles((opts) => __awaiter(void 0, void 0, void 0, function* () {
28
28
  // umi.ts
29
29
  api.writeTmpFile({
30
+ noPluginDir: true,
30
31
  path: 'umi.ts',
31
32
  tplPath: (0, path_1.join)(constants_1.TEMPLATES_DIR, 'umi.tpl'),
32
33
  context: {
34
+ mountElementId: api.config.mountElementId,
33
35
  rendererPath: yield api.applyPlugins({
34
36
  key: 'modifyRendererPath',
35
37
  initialValue: '@umijs/renderer-react',
@@ -54,6 +56,7 @@ exports.default = (api) => {
54
56
  key: 'addEntryImports',
55
57
  initialValue: [],
56
58
  })).join('\n'),
59
+ basename: api.config.base,
57
60
  },
58
61
  });
59
62
  // route.ts
@@ -70,7 +73,8 @@ exports.default = (api) => {
70
73
  // @/pages/
71
74
  const prefix = hasSrc ? '../../../src/pages/' : '../../pages/';
72
75
  api.writeTmpFile({
73
- path: 'core/route.ts',
76
+ noPluginDir: true,
77
+ path: 'core/route.tsx',
74
78
  tplPath: (0, path_1.join)(constants_1.TEMPLATES_DIR, 'route.tpl'),
75
79
  context: {
76
80
  routes: JSON.stringify(routes),
@@ -99,17 +103,19 @@ exports.default = (api) => {
99
103
  initialValue: [
100
104
  // TODO: support these methods
101
105
  // 'modifyClientRenderOpts',
102
- // 'patchRoutes',
106
+ 'patchRoutes',
103
107
  'rootContainer',
104
108
  'innerProvider',
105
109
  'i18nProvider',
110
+ 'accessProvider',
106
111
  'dataflowProvider',
107
112
  'outerProvider',
108
- // 'render',
113
+ 'render',
109
114
  // 'onRouteChange',
110
115
  ],
111
116
  });
112
117
  api.writeTmpFile({
118
+ noPluginDir: true,
113
119
  path: 'core/plugin.ts',
114
120
  tplPath: (0, path_1.join)(constants_1.TEMPLATES_DIR, 'plugin.tpl'),
115
121
  context: {
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ exports.default = () => {
15
15
  require.resolve('./features/polyfill/polyfill'),
16
16
  require.resolve('./features/tmpFiles/tmpFiles'),
17
17
  require.resolve('./features/transform/transform'),
18
+ require.resolve('./features/lowImport/lowImport'),
18
19
  // commands
19
20
  require.resolve('./commands/build'),
20
21
  require.resolve('./commands/config/config'),
package/dist/libs/scan.js CHANGED
@@ -87,6 +87,7 @@ function scan(opts) {
87
87
  const depPath = queueDeps.shift();
88
88
  if (cache.has(depPath))
89
89
  continue;
90
+ // TODO: use parseModule in bundler-utils
90
91
  const content = yield getContent(depPath);
91
92
  const { deps } = yield scanContent({ content });
92
93
  cache.set(depPath, deps);
@@ -7,6 +7,7 @@ const utils_1 = require("@umijs/utils");
7
7
  const assert_1 = __importDefault(require("assert"));
8
8
  const fs_1 = require("fs");
9
9
  const path_1 = require("path");
10
+ const transformIEAR_1 = __importDefault(require("./utils/transformIEAR"));
10
11
  const isTypeScriptFile_1 = require("./utils/isTypeScriptFile");
11
12
  exports.default = (api) => {
12
13
  [
@@ -52,7 +53,7 @@ exports.default = (api) => {
52
53
  // 'modifyExportRouteMap',
53
54
  // 'modifyPublicPathStr',
54
55
  'modifyRendererPath',
55
- // 'modifyRoutes',
56
+ 'modifyRoutes',
56
57
  ].forEach((name) => {
57
58
  api.registerMethod({ name });
58
59
  });
@@ -60,7 +61,9 @@ exports.default = (api) => {
60
61
  name: 'writeTmpFile',
61
62
  fn(opts) {
62
63
  (0, assert_1.default)(api.service.stage >= api.ServiceStage.runCommand, `api.writeTmpFile() should not execute in register stage.`);
63
- const absPath = (0, path_1.join)(api.paths.absTmpPath, opts.path);
64
+ const absPath = (0, path_1.join)(api.paths.absTmpPath,
65
+ // @ts-ignore
66
+ this.plugin.key && !opts.noPluginDir ? `plugin-${this.plugin.key}` : '', opts.path);
64
67
  utils_1.fsExtra.mkdirpSync((0, path_1.dirname)(absPath));
65
68
  let content = opts.content;
66
69
  if (!content) {
@@ -77,10 +80,15 @@ exports.default = (api) => {
77
80
  (0, isTypeScriptFile_1.isTypeScriptFile)(opts.path) && `// @ts-nocheck`,
78
81
  '// This file is generated by Umi automatically',
79
82
  '// DO NOT CHANGE IT MANUALLY!',
80
- content,
83
+ content.trim(),
84
+ '',
81
85
  ]
82
86
  .filter((text) => text !== false)
83
87
  .join('\n');
88
+ // transform imports for all javascript-like files
89
+ if (/\.(t|j)sx?$/.test(absPath)) {
90
+ content = (0, transformIEAR_1.default)({ content, path: absPath }, api);
91
+ }
84
92
  if (!(0, fs_1.existsSync)(absPath) || (0, fs_1.readFileSync)(absPath, 'utf-8') !== content) {
85
93
  (0, fs_1.writeFileSync)(absPath, content, 'utf-8');
86
94
  }
package/dist/types.d.ts CHANGED
@@ -4,6 +4,7 @@ import type WebpackChain from '@umijs/bundler-webpack/compiled/webpack-5-chain';
4
4
  import type { IAdd, IEvent, IModify, IRoute as ICoreRoute, IServicePluginAPI, PluginAPI } from '@umijs/core';
5
5
  import { Env } from '@umijs/core';
6
6
  import type { CheerioAPI } from '@umijs/utils/compiled/cheerio';
7
+ import type { InlineConfig as ViteInlineConfig } from 'vite';
7
8
  export declare type IScript = Partial<{
8
9
  async: boolean;
9
10
  charset: string;
@@ -48,6 +49,7 @@ export declare type IApi = PluginAPI & IServicePluginAPI & {
48
49
  restartServer: () => void;
49
50
  writeTmpFile: (opts: {
50
51
  path: string;
52
+ noPluginDir?: boolean;
51
53
  content?: string;
52
54
  tpl?: string;
53
55
  tplPath?: string;
@@ -129,11 +131,12 @@ export declare type IApi = PluginAPI & IServicePluginAPI & {
129
131
  path: string;
130
132
  }>;
131
133
  modifyRendererPath: IModify<string, {}>;
134
+ modifyRoutes: IModify<Record<string, IRoute>, {}>;
132
135
  modifyWebpackConfig: IModify<webpack.Configuration, {
133
136
  webpack: typeof webpack;
134
137
  env: Env;
135
138
  }>;
136
- modifyViteConfig: IModify<webpack.Configuration, {
139
+ modifyViteConfig: IModify<ViteInlineConfig, {
137
140
  env: Env;
138
141
  }>;
139
142
  chainWebpack: {
@@ -0,0 +1,22 @@
1
+ import type { IApi } from '../types';
2
+ /**
3
+ * import/export/await-import/require match regular expression
4
+ *
5
+ * WHY: REGEXP
6
+ * ref: https://github.com/umijs/umi-next/pull/230
7
+ *
8
+ * TODO: more choices
9
+ * 1. fork es-module-lexer, support jsx
10
+ * 2. use sourcemap of esbuild
11
+ */
12
+ export declare const IEAR_REG_EXP: RegExp;
13
+ /**
14
+ * transform absolute import/export/await-import/require path
15
+ * @note use to vite can deps:
16
+ * transform to relative path for .umi dir imports
17
+ * prefix `@fs` for node_modules imports
18
+ */
19
+ export default function transformIEAR({ content, path }: {
20
+ content: string;
21
+ path: string;
22
+ }, api: IApi): string;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IEAR_REG_EXP = void 0;
4
+ const utils_1 = require("@umijs/utils");
5
+ const path_1 = require("path");
6
+ /**
7
+ * import/export/await-import/require match regular expression
8
+ *
9
+ * WHY: REGEXP
10
+ * ref: https://github.com/umijs/umi-next/pull/230
11
+ *
12
+ * TODO: more choices
13
+ * 1. fork es-module-lexer, support jsx
14
+ * 2. use sourcemap of esbuild
15
+ */
16
+ exports.IEAR_REG_EXP = new RegExp([
17
+ // match content before quote ($1)
18
+ '(',
19
+ [
20
+ // import/export statements
21
+ [
22
+ '(?:',
23
+ // match head
24
+ '(?:^|\\r|\\n|;)\\s*',
25
+ // match identifier
26
+ '(?:import|export)\\s+',
27
+ [
28
+ '(?:',
29
+ '(?:',
30
+ // match body
31
+ [
32
+ // match default & member import
33
+ [
34
+ // match default import
35
+ [
36
+ '(?:',
37
+ // match type import
38
+ '(?:type\\s*)?',
39
+ // match variable name
40
+ '[a-zA-Z_$][\\w_$]*\\s*,?\\s+',
41
+ // optional
42
+ ')?',
43
+ ].join(''),
44
+ // match member import/export (optional)
45
+ '(?:{[^}]+}\\s+)?',
46
+ ].join(''),
47
+ // match contents import/export
48
+ '(?:type\\s*)?\\*\\s+(?:as\\s+[a-zA-Z][\\w_$]*\\s+)?',
49
+ ].join('|'),
50
+ ')',
51
+ // match from
52
+ 'from\\s+',
53
+ // match direct file import
54
+ '|\\s*',
55
+ ')',
56
+ ].join(''),
57
+ ')',
58
+ ].join(''),
59
+ // import/require call
60
+ [
61
+ // match head (must be single function name)
62
+ '(?:^|[^a-zA-Z\\w_$\\.])',
63
+ // match call
64
+ '(?:import|require)\\(\\s*',
65
+ ].join(''),
66
+ ].join('|'),
67
+ ')',
68
+ '(?:',
69
+ // match quotes ($2)
70
+ `('|")`,
71
+ // match absolute file path ($3)
72
+ `(\\/.*[^\\\\])\\2`,
73
+ ')',
74
+ ].join(''),
75
+ // match full-content
76
+ 'g');
77
+ /**
78
+ * transform absolute import/export/await-import/require path
79
+ * @note use to vite can deps:
80
+ * transform to relative path for .umi dir imports
81
+ * prefix `@fs` for node_modules imports
82
+ */
83
+ function transformIEAR({ content, path }, api) {
84
+ return content.replace(exports.IEAR_REG_EXP, (_, prefix, quote, absPath) => {
85
+ if (absPath.startsWith(api.paths.absTmpPath)) {
86
+ // transform .umi absolute imports
87
+ absPath = (0, utils_1.winPath)((0, path_1.relative)((0, path_1.dirname)(path), absPath));
88
+ }
89
+ else if (absPath.includes('node_modules')) {
90
+ // transform node_modules absolute imports
91
+ absPath = `@fs${absPath}`;
92
+ }
93
+ return `${prefix}${quote}${absPath}${quote}`;
94
+ });
95
+ }
96
+ exports.default = transformIEAR;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umijs/preset-umi",
3
- "version": "4.0.0-beta.10",
3
+ "version": "4.0.0-beta.14",
4
4
  "description": "@umijs/preset-umi",
5
5
  "homepage": "https://github.com/umijs/umi-next/tree/master/packages/preset-umi#readme",
6
6
  "bugs": "https://github.com/umijs/umi-next/issues",
@@ -24,28 +24,30 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@types/multer": "1.4.7",
27
- "@umijs/ast": "4.0.0-beta.10",
28
- "@umijs/babel-preset-umi": "4.0.0-beta.10",
29
- "@umijs/bundler-utils": "4.0.0-beta.10",
30
- "@umijs/bundler-vite": "4.0.0-beta.10",
31
- "@umijs/bundler-webpack": "4.0.0-beta.10",
32
- "@umijs/core": "4.0.0-beta.10",
33
- "@umijs/renderer-react": "4.0.0-beta.10",
34
- "@umijs/server": "4.0.0-beta.10",
35
- "@umijs/utils": "4.0.0-beta.10",
27
+ "@umijs/ast": "4.0.0-beta.14",
28
+ "@umijs/babel-preset-umi": "4.0.0-beta.14",
29
+ "@umijs/bundler-utils": "4.0.0-beta.14",
30
+ "@umijs/bundler-vite": "4.0.0-beta.14",
31
+ "@umijs/bundler-webpack": "4.0.0-beta.14",
32
+ "@umijs/core": "4.0.0-beta.14",
33
+ "@umijs/renderer-react": "4.0.0-beta.14",
34
+ "@umijs/server": "4.0.0-beta.14",
35
+ "@umijs/utils": "4.0.0-beta.14",
36
36
  "current-script-polyfill": "1.0.0",
37
37
  "enhanced-resolve": "5.8.3",
38
+ "magic-string": "0.25.7",
38
39
  "path-to-regexp": "1.7.0",
39
- "react": "18.0.0-alpha-f2c381131-20211004",
40
- "react-dom": "18.0.0-alpha-f2c381131-20211004",
41
- "react-router": "6.0.0-beta.7",
42
- "react-router-dom": "6.0.0-beta.7"
40
+ "react": "18.0.0-rc.0",
41
+ "react-dom": "18.0.0-rc.0",
42
+ "react-router": "6.1.1",
43
+ "react-router-dom": "6.1.1"
43
44
  },
44
45
  "devDependencies": {
45
46
  "@types/body-parser": "1.19.2",
46
47
  "@types/multer": "1.4.7",
47
48
  "body-parser": "1.19.0",
48
- "multer": "1.4.3"
49
+ "multer": "1.4.3",
50
+ "vite": "2.7.6"
49
51
  },
50
52
  "publishConfig": {
51
53
  "access": "public"
@@ -1,6 +1,7 @@
1
1
  {{#plugins}}
2
2
  import * as Plugin_{{{ index }}} from '{{{ path }}}';
3
3
  {{/plugins}}
4
+ import { PluginManager } from 'umi';
4
5
 
5
6
  export function getPlugins() {
6
7
  return [
@@ -16,3 +17,16 @@ export function getPlugins() {
16
17
  export function getValidKeys() {
17
18
  return [{{#validKeys}}'{{{ . }}}',{{/validKeys}}];
18
19
  }
20
+
21
+ let pluginManager = null;
22
+ export function createPluginManager() {
23
+ pluginManager = PluginManager.create({
24
+ plugins: getPlugins(),
25
+ validKeys: getValidKeys(),
26
+ });
27
+ return pluginManager;
28
+ }
29
+
30
+ export function getPluginManager() {
31
+ return pluginManager;
32
+ }
package/templates/umi.tpl CHANGED
@@ -2,19 +2,40 @@
2
2
  {{{ importsAhead }}}
3
3
  import { renderClient } from '{{{ rendererPath }}}';
4
4
  import { getRoutes } from './core/route';
5
- import { getPlugins, getValidKeys } from './core/plugin';
6
- import { PluginManager } from 'umi';
5
+ import { createPluginManager } from './core/plugin';
6
+ import { ApplyPluginsType, PluginManager } from 'umi';
7
7
  {{{ imports }}}
8
8
 
9
9
  async function render() {
10
+ const pluginManager = createPluginManager();
11
+ const { routes, routeComponents } = await getRoutes(pluginManager);
12
+
13
+ // allow user to extend routes
14
+ pluginManager.applyPlugins({
15
+ key: 'patchRoutes',
16
+ type: 'event',
17
+ args: {
18
+ routes,
19
+ routeComponents,
20
+ },
21
+ });
10
22
  const context = {
11
- ...await getRoutes(),
12
- pluginManager: PluginManager.create({
13
- plugins: getPlugins(),
14
- validKeys: getValidKeys(),
15
- }),
23
+ routes,
24
+ routeComponents,
25
+ pluginManager,
26
+ rootElement: document.getElementById('{{{ mountElementId }}}'),
27
+ {{#basename}}
28
+ basename: '{{{ basename }}}',
29
+ {{/basename}}
16
30
  };
17
- return renderClient(context);
31
+
32
+ return (pluginManager.applyPlugins({
33
+ key: 'render',
34
+ type: ApplyPluginsType.compose,
35
+ initialValue() {
36
+ return renderClient(context);
37
+ },
38
+ }))();
18
39
  }
19
40
 
20
41
  {{{ entryCodeAhead }}}
@@ -1,2 +0,0 @@
1
- export declare class ModuleGraph {
2
- }
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ModuleGraph = void 0;
4
- class ModuleGraph {
5
- }
6
- exports.ModuleGraph = ModuleGraph;