@umijs/core 4.0.0-beta.9 → 4.0.0-rc.3

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.
@@ -1 +1 @@
1
- (function(){var e={958:function(e,n,r){const t=r(747);const o=r(622);const s=r(87);function log(e){console.log(`[dotenv][DEBUG] ${e}`)}const i="\n";const c=/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/;const u=/\\n/g;const l=/\r\n|\n|\r/;function parse(e,n){const r=Boolean(n&&n.debug);const t={};e.toString().split(l).forEach((function(e,n){const o=e.match(c);if(o!=null){const e=o[1];let n=o[2]||"";const r=n.length-1;const s=n[0]==='"'&&n[r]==='"';const c=n[0]==="'"&&n[r]==="'";if(c||s){n=n.substring(1,r);if(s){n=n.replace(u,i)}}else{n=n.trim()}t[e]=n}else if(r){log(`did not match key and value when parsing line ${n+1}: ${e}`)}}));return t}function resolveHome(e){return e[0]==="~"?o.join(s.homedir(),e.slice(1)):e}function config(e){let n=o.resolve(process.cwd(),".env");let r="utf8";let s=false;if(e){if(e.path!=null){n=resolveHome(e.path)}if(e.encoding!=null){r=e.encoding}if(e.debug!=null){s=true}}try{const e=parse(t.readFileSync(n,{encoding:r}),{debug:s});Object.keys(e).forEach((function(n){if(!Object.prototype.hasOwnProperty.call(process.env,n)){process.env[n]=e[n]}else if(s){log(`"${n}" is already defined in \`process.env\` and will not be overwritten`)}}));return{parsed:e}}catch(e){return{error:e}}}e.exports.config=config;e.exports.parse=parse},747:function(e){"use strict";e.exports=require("fs")},87:function(e){"use strict";e.exports=require("os")},622:function(e){"use strict";e.exports=require("path")}};var n={};function __nccwpck_require__(r){var t=n[r];if(t!==undefined){return t.exports}var o=n[r]={exports:{}};var s=true;try{e[r](o,o.exports,__nccwpck_require__);s=false}finally{if(s)delete n[r]}return o.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r=__nccwpck_require__(958);module.exports=r})();
1
+ (function(){var e={875:function(e,r,n){const o=n(147);const t=n(17);const s=n(37);const i=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/gm;function parse(e){const r={};let n=e.toString();n=n.replace(/\r\n?/gm,"\n");let o;while((o=i.exec(n))!=null){const e=o[1];let n=o[2]||"";n=n.trim();const t=n[0];n=n.replace(/^(['"`])([\s\S]*)\1$/gm,"$2");if(t==='"'){n=n.replace(/\\n/g,"\n");n=n.replace(/\\r/g,"\r")}r[e]=n}return r}function _log(e){console.log(`[dotenv][DEBUG] ${e}`)}function _resolveHome(e){return e[0]==="~"?t.join(s.homedir(),e.slice(1)):e}function config(e){let r=t.resolve(process.cwd(),".env");let n="utf8";const s=Boolean(e&&e.debug);const i=Boolean(e&&e.override);if(e){if(e.path!=null){r=_resolveHome(e.path)}if(e.encoding!=null){n=e.encoding}}try{const e=c.parse(o.readFileSync(r,{encoding:n}));Object.keys(e).forEach((function(r){if(!Object.prototype.hasOwnProperty.call(process.env,r)){process.env[r]=e[r]}else{if(i===true){process.env[r]=e[r]}if(s){if(i===true){_log(`"${r}" is already defined in \`process.env\` and WAS overwritten`)}else{_log(`"${r}" is already defined in \`process.env\` and was NOT overwritten`)}}}}));return{parsed:e}}catch(e){if(s){_log(`Failed to load ${r} ${e.message}`)}return{error:e}}}const c={config:config,parse:parse};e.exports.config=c.config;e.exports.parse=c.parse;e.exports=c},147:function(e){"use strict";e.exports=require("fs")},37:function(e){"use strict";e.exports=require("os")},17:function(e){"use strict";e.exports=require("path")}};var r={};function __nccwpck_require__(n){var o=r[n];if(o!==undefined){return o.exports}var t=r[n]={exports:{}};var s=true;try{e[n](t,t.exports,__nccwpck_require__);s=false}finally{if(s)delete r[n]}return t.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var n=__nccwpck_require__(875);module.exports=n})();
@@ -0,0 +1,73 @@
1
+ // TypeScript Version: 3.0
2
+ /// <reference types="node" />
3
+
4
+ export interface DotenvParseOutput {
5
+ [name: string]: string;
6
+ }
7
+
8
+ /**
9
+ * Parses a string or buffer in the .env file format into an object.
10
+ *
11
+ * See https://docs.dotenv.org
12
+ *
13
+ * @param src - contents to be parsed. example: `'DB_HOST=localhost'`
14
+ * @param options - additional options. example: `{ debug: true }`
15
+ * @returns an object with keys and values based on `src`. example: `{ DB_HOST : 'localhost' }`
16
+ */
17
+ export function parse<T extends DotenvParseOutput = DotenvParseOutput>(
18
+ src: string | Buffer
19
+ ): T;
20
+
21
+ export interface DotenvConfigOptions {
22
+ /**
23
+ * Default: `path.resolve(process.cwd(), '.env')`
24
+ *
25
+ * Specify a custom path if your file containing environment variables is located elsewhere.
26
+ *
27
+ * example: `require('dotenv').config({ path: '/custom/path/to/.env' })`
28
+ */
29
+ path?: string;
30
+
31
+ /**
32
+ * Default: `utf8`
33
+ *
34
+ * Specify the encoding of your file containing environment variables.
35
+ *
36
+ * example: `require('dotenv').config({ encoding: 'latin1' })`
37
+ */
38
+ encoding?: string;
39
+
40
+ /**
41
+ * Default: `false`
42
+ *
43
+ * Turn on logging to help debug why certain keys or values are not being set as you expect.
44
+ *
45
+ * example: `require('dotenv').config({ debug: process.env.DEBUG })`
46
+ */
47
+ debug?: boolean;
48
+
49
+ /**
50
+ * Default: `false`
51
+ *
52
+ * Override any environment variables that have already been set on your machine with values from your .env file.
53
+ *
54
+ * example: `require('dotenv').config({ override: true })`
55
+ */
56
+ override?: boolean;
57
+ }
58
+
59
+ export interface DotenvConfigOutput {
60
+ error?: Error;
61
+ parsed?: DotenvParseOutput;
62
+ }
63
+
64
+ /**
65
+ * Loads `.env` file contents into process.env.
66
+ *
67
+ * See https://docs.dotenv.org
68
+ *
69
+ * @param options - additional options. example: `{ path: './custom/path', encoding: 'latin1', debug: true, override: false }`
70
+ * @returns an object with a `parsed` key if successful or `error` key if an error occurred. example: { parsed: { KEY: 'value' } }
71
+ *
72
+ */
73
+ export function config(options?: DotenvConfigOptions): DotenvConfigOutput;
@@ -1 +1 @@
1
- {"name":"dotenv","license":"BSD-2-Clause","types":"types/index.d.ts"}
1
+ {"name":"dotenv","license":"BSD-2-Clause","types":"lib/main.d.ts"}
@@ -1 +1 @@
1
- (function(){var e={784:function(e){e.exports={diff:diff,jsonPatchPathConverter:jsonPatchPathConverter};function diff(e,r,t){if(!e||typeof e!="object"||!r||typeof r!="object"){throw new Error("both arguments must be objects or arrays")}t||(t=function(e){return e});function getDiff(e,r,a,n){var o=Object.keys(e);var c=o.length;var i=Object.keys(r);var f=i.length;var u;for(var p=0;p<c;p++){var s=Array.isArray(e)?Number(o[p]):o[p];if(!(s in r)){u=a.concat(s);n.remove.push({op:"remove",path:t(u)})}}for(var p=0;p<f;p++){var s=Array.isArray(r)?Number(i[p]):i[p];var v=e[s];var _=r[s];if(!(s in e)){u=a.concat(s);var h=r[s];n.add.push({op:"add",path:t(u),value:h})}else if(v!==_){if(Object(v)!==v||Object(_)!==_){u=pushReplace(u,a,s,n,t,r)}else{if(!Object.keys(v).length&&!Object.keys(_).length&&String(v)!=String(_)){u=pushReplace(u,a,s,n,t,r)}else{getDiff(e[s],r[s],a.concat(s),n)}}}}return n.remove.reverse().concat(n.replace).concat(n.add)}return getDiff(e,r,[],{remove:[],replace:[],add:[]})}function pushReplace(e,r,t,a,n,o){e=r.concat(t);a.replace.push({op:"replace",path:n(e),value:o[t]});return e}function jsonPatchPathConverter(e){return[""].concat(e).join("/")}}};var r={};function __nccwpck_require__(t){var a=r[t];if(a!==undefined){return a.exports}var n=r[t]={exports:{}};var o=true;try{e[t](n,n.exports,__nccwpck_require__);o=false}finally{if(o)delete r[t]}return n.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var t=__nccwpck_require__(784);module.exports=t})();
1
+ (function(){var e={277:function(e){e.exports={diff:diff,jsonPatchPathConverter:jsonPatchPathConverter};function diff(e,r,t){if(!e||typeof e!="object"||!r||typeof r!="object"){throw new Error("both arguments must be objects or arrays")}t||(t=function(e){return e});function getDiff(e,r,a,n){var o=Object.keys(e);var c=o.length;var i=Object.keys(r);var f=i.length;var u;for(var p=0;p<c;p++){var s=Array.isArray(e)?Number(o[p]):o[p];if(!(s in r)){u=a.concat(s);n.remove.push({op:"remove",path:t(u)})}}for(var p=0;p<f;p++){var s=Array.isArray(r)?Number(i[p]):i[p];var v=e[s];var _=r[s];if(!(s in e)){u=a.concat(s);var h=r[s];n.add.push({op:"add",path:t(u),value:h})}else if(v!==_){if(Object(v)!==v||Object(_)!==_){u=pushReplace(u,a,s,n,t,r)}else{if(!Object.keys(v).length&&!Object.keys(_).length&&String(v)!=String(_)){u=pushReplace(u,a,s,n,t,r)}else{getDiff(e[s],r[s],a.concat(s),n)}}}}return n.remove.reverse().concat(n.replace).concat(n.add)}return getDiff(e,r,[],{remove:[],replace:[],add:[]})}function pushReplace(e,r,t,a,n,o){e=r.concat(t);a.replace.push({op:"replace",path:n(e),value:o[t]});return e}function jsonPatchPathConverter(e){return[""].concat(e).join("/")}}};var r={};function __nccwpck_require__(t){var a=r[t];if(a!==undefined){return a.exports}var n=r[t]={exports:{}};var o=true;try{e[t](n,n.exports,__nccwpck_require__);o=false}finally{if(o)delete r[t]}return n.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var t=__nccwpck_require__(277);module.exports=t})();
@@ -114,7 +114,6 @@ class Config {
114
114
  let config = {};
115
115
  let files = [];
116
116
  for (const configFile of opts.configFiles) {
117
- files.push(configFile);
118
117
  if ((0, fs_1.existsSync)(configFile)) {
119
118
  utils_1.register.register({
120
119
  implementor: esbuild_1.default,
@@ -124,9 +123,13 @@ class Config {
124
123
  for (const file of utils_1.register.getFiles()) {
125
124
  delete require.cache[file];
126
125
  }
126
+ // includes the config File
127
127
  files.push(...utils_1.register.getFiles());
128
128
  utils_1.register.restore();
129
129
  }
130
+ else {
131
+ files.push(configFile);
132
+ }
130
133
  }
131
134
  return {
132
135
  config,
@@ -4,4 +4,5 @@ export declare function addParentRoute(opts: {
4
4
  addToAll?: boolean;
5
5
  target: IRoute;
6
6
  routes: Record<string, IRoute>;
7
+ test?: Function;
7
8
  }): void;
@@ -4,13 +4,16 @@ exports.addParentRoute = void 0;
4
4
  function addParentRoute(opts) {
5
5
  if (opts.addToAll) {
6
6
  for (const id of Object.keys(opts.routes)) {
7
- if (opts.routes[id].parentId === undefined) {
7
+ if (opts.routes[id].parentId === undefined &&
8
+ (!opts.test || opts.test(opts.routes[id]))) {
8
9
  opts.routes[id].parentId = opts.target.id;
9
10
  }
10
11
  }
11
12
  }
12
13
  else if (opts.id) {
13
- opts.routes[opts.id].parentId = opts.target.id;
14
+ if (!opts.test || opts.test(opts.routes[opts.id])) {
15
+ opts.routes[opts.id].parentId = opts.target.id;
16
+ }
14
17
  }
15
18
  else {
16
19
  throw new Error(`addParentRoute failed, opts.addToAll or opts.id must be supplied.`);
@@ -10,8 +10,12 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  }
11
11
  return t;
12
12
  };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
13
16
  Object.defineProperty(exports, "__esModule", { value: true });
14
17
  exports.getConfigRoutes = void 0;
18
+ const assert_1 = __importDefault(require("assert"));
15
19
  function getConfigRoutes(opts) {
16
20
  const memo = { ret: {}, id: 1 };
17
21
  transformRoutes({ routes: opts.routes, parentId: undefined, memo });
@@ -24,6 +28,7 @@ function transformRoutes(opts) {
24
28
  });
25
29
  }
26
30
  function transformRoute(opts) {
31
+ (0, assert_1.default)(!opts.route.children, 'children is not allowed in route props, use routes instead.');
27
32
  const id = String(opts.memo.id++);
28
33
  const _a = opts.route, { routes, component } = _a, routeProps = __rest(_a, ["routes", "component"]);
29
34
  opts.memo.ret[id] = Object.assign(Object.assign(Object.assign(Object.assign({}, routeProps), { path: opts.route.path }), (component ? { file: component } : {})), { parentId: opts.parentId, id });
@@ -1,4 +1,5 @@
1
1
  export declare function getConventionRoutes(opts: {
2
2
  base: string;
3
3
  prefix?: string;
4
+ exclude?: RegExp[];
4
5
  }): any;
@@ -1,11 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.getConventionRoutes = void 0;
7
4
  const utils_1 = require("@umijs/utils");
8
- const assert_1 = __importDefault(require("assert"));
9
5
  const fs_1 = require("fs");
10
6
  const path_1 = require("path");
11
7
  const defineRoutes_1 = require("./defineRoutes");
@@ -13,17 +9,16 @@ const utils_2 = require("./utils");
13
9
  // opts.base: path of pages
14
10
  function getConventionRoutes(opts) {
15
11
  const files = {};
16
- (0, assert_1.default)((0, fs_1.existsSync)(opts.base) && (0, fs_1.statSync)(opts.base).isDirectory(), `Convention routes base not found.`);
12
+ if (!((0, fs_1.existsSync)(opts.base) && (0, fs_1.statSync)(opts.base).isDirectory())) {
13
+ return {};
14
+ }
17
15
  visitFiles({
18
16
  dir: opts.base,
19
17
  visitor: (file) => {
20
18
  const routeId = (0, utils_2.createRouteId)(file);
21
- if ((0, utils_2.isRouteModuleFile)({ file })) {
19
+ if ((0, utils_2.isRouteModuleFile)({ file: (0, utils_1.winPath)(file), exclude: opts.exclude })) {
22
20
  files[routeId] = (0, utils_1.winPath)(file);
23
21
  }
24
- else {
25
- throw new Error(`Invalid route module file: ${(0, path_1.join)(opts.base, file)}`);
26
- }
27
22
  },
28
23
  });
29
24
  const routeIds = Object.keys(files).sort(utils_2.byLongestFirst);
@@ -52,13 +47,13 @@ function visitFiles(opts) {
52
47
  visitFiles(Object.assign(Object.assign({}, opts), { dir: file }));
53
48
  }
54
49
  else if (stat.isFile() &&
55
- ['.tsx', '.ts', '.js', '.jsx'].includes((0, path_1.extname)(file))) {
50
+ ['.tsx', '.ts', '.js', '.jsx', '.md', '.mdx'].includes((0, path_1.extname)(file))) {
56
51
  opts.visitor((0, path_1.relative)(opts.baseDir, file));
57
52
  }
58
53
  }
59
54
  }
60
55
  function createRoutePath(routeId) {
61
- const path = routeId
56
+ let path = routeId
62
57
  // routes/$ -> routes/*
63
58
  // routes/nested/$.tsx (with a "routes/nested.tsx" layout)
64
59
  .replace(/^\$$/, '*')
@@ -69,5 +64,7 @@ function createRoutePath(routeId) {
69
64
  .replace(/\$/g, ':')
70
65
  // routes/not.nested -> routes/not/nested
71
66
  .replace(/\./g, '/');
72
- return /\b\/?index$/.test(path) ? path.replace(/\/?index$/, '') : path;
67
+ path = /\b\/?index$/.test(path) ? path.replace(/\/?index$/, '') : path;
68
+ path = /\b\/?README$/.test(path) ? path.replace(/\/?README$/, '') : path;
69
+ return path;
73
70
  }
@@ -4,4 +4,5 @@ export declare function byLongestFirst(a: string, b: string): number;
4
4
  export declare function findParentRouteId(routeIds: string[], childRouteId: string): string | undefined;
5
5
  export declare function isRouteModuleFile(opts: {
6
6
  file: string;
7
+ exclude?: RegExp[];
7
8
  }): boolean;
@@ -21,6 +21,14 @@ function findParentRouteId(routeIds, childRouteId) {
21
21
  exports.findParentRouteId = findParentRouteId;
22
22
  const routeModuleExts = ['.js', '.jsx', '.ts', '.tsx', '.md', '.mdx'];
23
23
  function isRouteModuleFile(opts) {
24
+ // TODO: add cache strategy
25
+ for (const excludeRegExp of opts.exclude || []) {
26
+ if (opts.file &&
27
+ excludeRegExp instanceof RegExp &&
28
+ excludeRegExp.test(opts.file)) {
29
+ return false;
30
+ }
31
+ }
24
32
  return routeModuleExts.includes((0, path_1.extname)(opts.file));
25
33
  }
26
34
  exports.isRouteModuleFile = isRouteModuleFile;
@@ -1,4 +1,4 @@
1
- import { EnableBy, IPluginConfig } from '../types';
1
+ import { EnableBy, Env, IPluginConfig } from '../types';
2
2
  declare type PluginType = 'plugin' | 'preset';
3
3
  interface IOpts {
4
4
  path: string;
@@ -21,13 +21,15 @@ export declare class Plugin {
21
21
  apply: Function;
22
22
  config: IPluginConfig;
23
23
  enableBy: EnableBy | ((opts: {
24
+ userConfig: any;
24
25
  config: any;
26
+ env: Env;
25
27
  }) => boolean);
26
28
  constructor(opts: IOpts);
27
29
  merge(opts: {
28
30
  key?: string;
29
31
  config?: IPluginConfig;
30
- enableBy?: EnableBy | (() => boolean);
32
+ enableBy?: any;
31
33
  }): void;
32
34
  getId(opts: {
33
35
  pkg: any;
@@ -25,7 +25,7 @@ class Plugin {
25
25
  let pkg = null;
26
26
  // path is the package entry
27
27
  let isPkgEntry = false;
28
- const pkgJSONPath = utils_1.pkgUp.sync({ cwd: this.path });
28
+ const pkgJSONPath = utils_1.pkgUp.pkgUpSync({ cwd: this.path });
29
29
  if (pkgJSONPath) {
30
30
  pkg = require(pkgJSONPath);
31
31
  isPkgEntry =
@@ -114,9 +114,9 @@ class Plugin {
114
114
  .split(',')
115
115
  .filter(Boolean),
116
116
  // dependencies
117
- ...Object.keys(opts.pkg.devDependencies || {})
118
- .concat(Object.keys(opts.pkg.dependencies || {}))
119
- .filter(Plugin.isPluginOrPreset.bind(null, type)),
117
+ // ...Object.keys(opts.pkg.devDependencies || {})
118
+ // .concat(Object.keys(opts.pkg.dependencies || {}))
119
+ // .filter(Plugin.isPluginOrPreset.bind(null, type)),
120
120
  // user config
121
121
  ...(opts.userConfig[types] || []),
122
122
  ].map((path) => {
@@ -1,5 +1,5 @@
1
1
  import { logger } from '@umijs/utils';
2
- import { EnableBy, IPluginConfig } from '../types';
2
+ import { EnableBy, Env, IPluginConfig } from '../types';
3
3
  import { IOpts as ICommandOpts } from './command';
4
4
  import { IGeneratorOpts } from './generator';
5
5
  import { IOpts as IHookOpts } from './hook';
@@ -17,7 +17,10 @@ export declare class PluginAPI {
17
17
  describe(opts: {
18
18
  key?: string;
19
19
  config?: IPluginConfig;
20
- enableBy?: EnableBy | (() => boolean);
20
+ enableBy?: EnableBy | ((enableByOpts: {
21
+ userConfig: any;
22
+ env: Env;
23
+ }) => boolean);
21
24
  }): void;
22
25
  registerCommand(opts: Omit<ICommandOpts, 'plugin'> & {
23
26
  alias?: string | string[];
@@ -15,7 +15,15 @@ interface IOpts {
15
15
  }
16
16
  export declare class Service {
17
17
  private opts;
18
- appData: Record<string, any>;
18
+ appData: {
19
+ deps?: Record<string, {
20
+ version: string;
21
+ matches: string[];
22
+ subpaths: string[];
23
+ external?: boolean;
24
+ }>;
25
+ [key: string]: any;
26
+ };
19
27
  args: yParser.Arguments;
20
28
  commands: Record<string, Command>;
21
29
  generators: Record<string, Generator>;
@@ -36,6 +44,7 @@ export declare class Service {
36
44
  absOutputPath?: string;
37
45
  };
38
46
  plugins: Record<string, Plugin>;
47
+ keyToPluginMap: Record<string, Plugin>;
39
48
  pluginMethods: Record<string, {
40
49
  plugin: Plugin;
41
50
  fn: Function;
@@ -44,7 +53,14 @@ export declare class Service {
44
53
  stage: ServiceStage;
45
54
  userConfig: Record<string, any>;
46
55
  configManager: Config | null;
47
- pkg: Record<string, string | Record<string, any>>;
56
+ pkg: {
57
+ name?: string;
58
+ version?: string;
59
+ dependencies?: Record<string, string>;
60
+ devDependencies?: Record<string, string>;
61
+ [key: string]: any;
62
+ };
63
+ pkgPath: string;
48
64
  constructor(opts: IOpts);
49
65
  applyPlugins<T>(opts: {
50
66
  key: string;
@@ -66,7 +82,7 @@ export declare class Service {
66
82
  presets?: Plugin[];
67
83
  plugins: Plugin[];
68
84
  }): Promise<any>;
69
- isPluginEnable(hook: Hook): boolean;
85
+ isPluginEnable(hook: Hook | string): boolean;
70
86
  }
71
87
  export interface IServicePluginAPI {
72
88
  appData: typeof Service.prototype.appData;
@@ -76,9 +92,12 @@ export interface IServicePluginAPI {
76
92
  cwd: typeof Service.prototype.cwd;
77
93
  generators: typeof Service.prototype.generators;
78
94
  pkg: typeof Service.prototype.pkg;
95
+ pkgPath: typeof Service.prototype.pkgPath;
79
96
  name: typeof Service.prototype.name;
80
97
  paths: Required<typeof Service.prototype.paths>;
81
98
  userConfig: typeof Service.prototype.userConfig;
99
+ env: typeof Service.prototype.env;
100
+ isPluginEnable: typeof Service.prototype.isPluginEnable;
82
101
  onCheck: IEvent<null>;
83
102
  onStart: IEvent<null>;
84
103
  modifyAppData: IModify<typeof Service.prototype.appData, null>;
@@ -41,12 +41,14 @@ class Service {
41
41
  this.paths = {};
42
42
  // preset is plugin with different type
43
43
  this.plugins = {};
44
+ this.keyToPluginMap = {};
44
45
  this.pluginMethods = {};
45
46
  this.skipPluginIds = new Set();
46
47
  this.stage = types_1.ServiceStage.uninitialized;
47
48
  this.userConfig = {};
48
49
  this.configManager = null;
49
50
  this.pkg = {};
51
+ this.pkgPath = '';
50
52
  this.cwd = opts.cwd;
51
53
  this.env = opts.env;
52
54
  this.opts = opts;
@@ -135,19 +137,23 @@ class Service {
135
137
  (0, env_1.loadEnv)({ cwd: this.cwd, envFile: '.env' });
136
138
  // get pkg from package.json
137
139
  let pkg = {};
140
+ let pkgPath = '';
138
141
  try {
139
142
  pkg = require((0, path_1.join)(this.cwd, 'package.json'));
143
+ pkgPath = (0, path_1.join)(this.cwd, 'package.json');
140
144
  }
141
145
  catch (_e) {
142
146
  // APP_ROOT
143
147
  if (this.cwd !== process.cwd()) {
144
148
  try {
145
149
  pkg = require((0, path_1.join)(process.cwd(), 'package.json'));
150
+ pkgPath = (0, path_1.join)(process.cwd(), 'package.json');
146
151
  }
147
152
  catch (_e) { }
148
153
  }
149
154
  }
150
155
  this.pkg = pkg;
156
+ this.pkgPath = pkgPath;
151
157
  // get user config
152
158
  const configManager = new config_1.Config({
153
159
  cwd: this.cwd,
@@ -181,6 +187,10 @@ class Service {
181
187
  while (plugins.length) {
182
188
  yield this.initPlugin({ plugin: plugins.shift(), plugins });
183
189
  }
190
+ // keyToPluginMap
191
+ for (const id of Object.keys(this.plugins)) {
192
+ this.keyToPluginMap[this.plugins[id].key] = this.plugins[id];
193
+ }
184
194
  // collect configSchemas and configDefaults
185
195
  for (const id of Object.keys(this.plugins)) {
186
196
  const { config, key } = this.plugins[id];
@@ -197,15 +207,15 @@ class Service {
197
207
  env: this.env,
198
208
  prefix: this.opts.frameworkName || constants_1.DEFAULT_FRAMEWORK_NAME,
199
209
  });
200
- if (this.config.outputPath) {
201
- paths.absOutputPath = (0, path_1.join)(this.cwd, this.config.outputPath);
202
- }
203
210
  this.stage = types_1.ServiceStage.resolveConfig;
204
211
  const config = yield this.applyPlugins({
205
212
  key: 'modifyConfig',
206
- initialValue: configManager.getConfig({
213
+ // why clone deep?
214
+ // user may change the config in modifyConfig
215
+ // e.g. memo.alias = xxx
216
+ initialValue: utils_1.lodash.cloneDeep(configManager.getConfig({
207
217
  schemas: this.configSchemas,
208
- }).config,
218
+ }).config),
209
219
  args: { paths },
210
220
  });
211
221
  const defaultConfig = yield this.applyPlugins({
@@ -213,6 +223,9 @@ class Service {
213
223
  initialValue: this.configDefaults,
214
224
  });
215
225
  this.config = utils_1.lodash.merge(defaultConfig, config);
226
+ if (this.config.outputPath) {
227
+ paths.absOutputPath = (0, path_1.join)(this.cwd, this.config.outputPath);
228
+ }
216
229
  this.paths = yield this.applyPlugins({
217
230
  key: 'modifyPaths',
218
231
  initialValue: paths,
@@ -226,6 +239,7 @@ class Service {
226
239
  // base
227
240
  cwd: this.cwd,
228
241
  pkg,
242
+ pkgPath,
229
243
  plugins,
230
244
  presets,
231
245
  name,
@@ -299,9 +313,12 @@ class Service {
299
313
  'config',
300
314
  'cwd',
301
315
  'pkg',
316
+ 'pkgPath',
302
317
  'name',
303
318
  'paths',
304
319
  'userConfig',
320
+ 'env',
321
+ 'isPluginEnable',
305
322
  ],
306
323
  staticProps: {
307
324
  ApplyPluginsType: types_1.ApplyPluginsType,
@@ -315,6 +332,9 @@ class Service {
315
332
  if ((0, utils_2.isPromise)(ret)) {
316
333
  ret = yield ret;
317
334
  }
335
+ if (opts.plugin.type === 'plugin') {
336
+ (0, assert_1.default)(!ret, `plugin should return nothing`);
337
+ }
318
338
  if (ret === null || ret === void 0 ? void 0 : ret.presets) {
319
339
  ret.presets = ret.presets.map((preset) => new plugin_1.Plugin({
320
340
  path: preset,
@@ -333,15 +353,30 @@ class Service {
333
353
  });
334
354
  }
335
355
  isPluginEnable(hook) {
336
- const { id, key, enableBy } = hook.plugin;
356
+ let plugin;
357
+ if (hook.plugin) {
358
+ plugin = hook.plugin;
359
+ }
360
+ else {
361
+ plugin = this.keyToPluginMap[hook];
362
+ }
363
+ const { id, key, enableBy } = plugin;
337
364
  if (this.skipPluginIds.has(id))
338
365
  return false;
339
366
  if (this.userConfig[key] === false)
340
367
  return false;
341
- if (enableBy === types_1.EnableBy.config && !(key in this.config))
368
+ if (this.config[key] === false)
342
369
  return false;
370
+ if (enableBy === types_1.EnableBy.config) {
371
+ // TODO: 提供单独的命令用于启用插件
372
+ return key in this.userConfig;
373
+ }
343
374
  if (typeof enableBy === 'function')
344
- return enableBy({ config: this.config });
375
+ return enableBy({
376
+ userConfig: this.userConfig,
377
+ config: this.config,
378
+ env: this.env,
379
+ });
345
380
  // EnableBy.register
346
381
  return true;
347
382
  }
package/dist/types.d.ts CHANGED
@@ -44,6 +44,7 @@ export interface IRoute {
44
44
  file: string;
45
45
  id: string;
46
46
  parentId?: string;
47
+ [key: string]: any;
47
48
  }
48
49
  export interface IEvent<T> {
49
50
  (fn: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umijs/core",
3
- "version": "4.0.0-beta.9",
3
+ "version": "4.0.0-rc.3",
4
4
  "homepage": "https://github.com/umijs/umi-next/tree/master/packages/core#readme",
5
5
  "bugs": "https://github.com/umijs/umi-next/issues",
6
6
  "repository": {
@@ -20,14 +20,14 @@
20
20
  "dev": "pnpm build -- --watch"
21
21
  },
22
22
  "dependencies": {
23
- "@umijs/bundler-utils": "4.0.0-beta.9",
24
- "@umijs/utils": "4.0.0-beta.9"
23
+ "@umijs/bundler-utils": "4.0.0-rc.3",
24
+ "@umijs/utils": "4.0.0-rc.3"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@hapi/joi": "17.1.1",
28
- "@types/hapi__joi": "17.1.7",
29
- "dotenv": "10.0.0",
30
- "just-diff": "3.1.1",
28
+ "@types/hapi__joi": "17.1.8",
29
+ "dotenv": "16.0.0",
30
+ "just-diff": "5.0.1",
31
31
  "tapable": "2.2.1"
32
32
  },
33
33
  "publishConfig": {