@roots/bud-build 5.4.0 → 5.6.1

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 (42) hide show
  1. package/README.md +1 -1
  2. package/lib/cjs/Build/config/builder.js +69 -162
  3. package/lib/cjs/Build/config/builder.unwrap.js +35 -0
  4. package/lib/cjs/Build/index.js +156 -49
  5. package/lib/cjs/Build/items.js +101 -111
  6. package/lib/cjs/Build/loaders.js +55 -53
  7. package/lib/cjs/Build/rules.js +18 -24
  8. package/lib/cjs/Item/index.js +36 -24
  9. package/lib/cjs/Loader/index.js +10 -56
  10. package/lib/cjs/Rule/index.js +29 -43
  11. package/lib/cjs/index.js +1 -8
  12. package/lib/cjs/shared/Base.js +10 -1
  13. package/lib/tsconfig.tsbuildinfo +1 -1
  14. package/package.json +5 -5
  15. package/types/Build/config/builder.d.ts +6 -1
  16. package/types/Build/config/builder.d.ts.map +1 -1
  17. package/types/Build/config/builder.unwrap.d.ts +19 -0
  18. package/types/Build/config/builder.unwrap.d.ts.map +1 -0
  19. package/types/Build/index.d.ts +65 -13
  20. package/types/Build/index.d.ts.map +1 -1
  21. package/types/Build/items.d.ts +62 -71
  22. package/types/Build/items.d.ts.map +1 -1
  23. package/types/Build/loaders.d.ts +45 -54
  24. package/types/Build/loaders.d.ts.map +1 -1
  25. package/types/Build/rules.d.ts +13 -14
  26. package/types/Build/rules.d.ts.map +1 -1
  27. package/types/Item/index.d.ts +19 -11
  28. package/types/Item/index.d.ts.map +1 -1
  29. package/types/Loader/index.d.ts +10 -24
  30. package/types/Loader/index.d.ts.map +1 -1
  31. package/types/Rule/index.d.ts +23 -31
  32. package/types/Rule/index.d.ts.map +1 -1
  33. package/types/index.d.ts +1 -8
  34. package/types/index.d.ts.map +1 -1
  35. package/types/shared/Base.d.ts +5 -1
  36. package/types/shared/Base.d.ts.map +1 -1
  37. package/lib/cjs/Item/item.dependencies.js +0 -6
  38. package/lib/cjs/Item/item.interface.js +0 -7
  39. package/types/Item/item.dependencies.d.ts +0 -4
  40. package/types/Item/item.dependencies.d.ts.map +0 -1
  41. package/types/Item/item.interface.d.ts +0 -2
  42. package/types/Item/item.interface.d.ts.map +0 -1
package/README.md CHANGED
@@ -24,7 +24,7 @@ yarn add @roots/bud-build --dev
24
24
 
25
25
  ## Documentation
26
26
 
27
- For more information on utilizing this package [check out our dedicated docs](https://budjs.netlify.app)
27
+ For more information on utilizing this package [check out our dedicated docs](https://bud.js.org)
28
28
 
29
29
  ## Community
30
30
 
@@ -1,74 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.build = void 0;
4
- const bud_support_1 = require("@roots/bud-support");
5
- const path_1 = require("path");
4
+ const builder_unwrap_1 = require("./builder.unwrap");
6
5
  const filenameFormat_1 = require("./filenameFormat");
7
- const { dirname } = path_1.posix;
8
6
  /**
9
- * Filters framework values and returns a webpack configuration
7
+ * Initializes configuration builder hooks
8
+ *
9
+ * @remarks
10
+ * All hooks in the `build` namespace are initialized here with
11
+ * the exception of `build.cache` which is handled in {@link Framework.cache}
10
12
  *
11
13
  * @param app - the Framework instance
14
+ * @returns Promise
12
15
  *
13
16
  * @public
14
17
  */
15
18
  async function build(app) {
19
+ /**
20
+ * App bound unwrap
21
+ */
22
+ const unwrap = builder_unwrap_1.unwrap.bind(app);
16
23
  app.hooks
17
- .async('build', async () => {
18
- const entry = await app.hooks.filterAsync('build.entry');
19
- const plugins = await app.hooks.filterAsync('build.plugins');
20
- const resolve = await app.hooks.filterAsync('build.resolve');
21
- return {
22
- entry,
23
- plugins,
24
- resolve,
25
- bail: app.hooks.filter('build.bail'),
26
- cache: app.hooks.filter('build.cache'),
27
- context: app.hooks.filter('build.context'),
28
- devtool: app.hooks.filter('build.devtool'),
29
- experiments: app.hooks.filter('build.experiments'),
30
- externals: app.hooks.filter('build.externals'),
31
- infrastructureLogging: app.hooks.filter('build.infrastructureLogging'),
32
- mode: app.hooks.filter('build.mode'),
33
- module: app.hooks.filter('build.module'),
34
- name: app.hooks.filter('build.name'),
35
- node: app.hooks.filter('build.node'),
36
- output: app.hooks.filter('build.output'),
37
- optimization: app.hooks.filter('build.optimization'),
38
- parallelism: app.hooks.filter('build.parallelism'),
39
- performance: app.hooks.filter('build.performance'),
40
- profile: app.hooks.filter('build.profile'),
41
- recordsPath: app.hooks.filter('build.recordsPath'),
42
- stats: app.hooks.filter('build.stats'),
43
- target: app.hooks.filter('build.target'),
44
- watch: app.hooks.filter('build.watch'),
45
- watchOptions: app.hooks.filter('build.watchOptions'),
46
- };
47
- })
48
- /**
49
- * build.bail
50
- */
51
- .hooks.on('build.bail', () => app.store.get('build.bail'))
52
- /**
53
- * build.context
54
- */
55
- .hooks.on('build.context', () => app.path('project'))
56
- /**
57
- * build.devtool
58
- */
59
- .hooks.on('build.devtool', () => app.store.get('build.devtool'))
60
- /**
61
- * build.infrastructureLogging
62
- */
63
- .hooks.on('build.infrastructureLogging', () => app.store.get('build.infrastructureLogging'))
64
- /**
65
- * build.mode
66
- */
67
- .hooks.on('build.mode', () => app.mode)
68
- /**
69
- * build.module
70
- */
24
+ .on('build.cache', () => app.cache.configuration)
25
+ .hooks.on('build.context', () => app.context.projectDir)
26
+ .hooks.on('build.mode', app.mode)
71
27
  .hooks.on('build.module', () => ({
28
+ noParse: app.hooks.filter('build.module.noParse'),
72
29
  rules: app.hooks.filter('build.module.rules'),
73
30
  unsafeCache: app.hooks.filter('build.module.unsafeCache'),
74
31
  }))
@@ -79,48 +36,8 @@ async function build(app) {
79
36
  },
80
37
  ...app.hooks.filter('build.module.rules.after'),
81
38
  ])
82
- .hooks.on('build.module.rules.oneOf', () => Object.values(app.build.rules).map(rule => rule.make()))
83
- .hooks.on('build.module.rules.before', () => [
84
- {
85
- test: /\.[cm]?(jsx?|tsx?)$/,
86
- parser: {
87
- requireEnsure: false,
88
- },
89
- },
90
- ])
91
- .hooks.on('build.module.rules.after', () => [])
92
- .hooks.on('build.module.unsafeCache', () => app.store.get('build.module.unsafeCache'))
93
- /**
94
- * build.name
95
- */
96
- .hooks.on('build.name', () => app.name)
97
- /**
98
- * build.node
99
- */
100
- .hooks.on('build.node', () => false)
101
- /**
102
- * build.optimization
103
- */
104
- .hooks.on('build.optimization', () => ({
105
- emitOnErrors: app.hooks.filter('build.optimization.emitOnErrors'),
106
- minimize: app.hooks.filter('build.optimization.minimize'),
107
- minimizer: app.hooks.filter('build.optimization.minimizer'),
108
- moduleIds: app.hooks.filter('build.optimization.moduleIds'),
109
- runtimeChunk: app.hooks.filter('build.optimization.runtimeChunk'),
110
- splitChunks: app.hooks.filter('build.optimization.splitChunks'),
111
- }))
112
- .hooks.on('build.optimization.emitOnErrors', () => app.store.get('build.optimization.emitOnErrors'))
113
- .hooks.on('build.optimization.minimize', () => app.store.is('features.minimize', true))
114
- .hooks.on('build.optimization.minimizer', () => ['...'])
115
- .hooks.on('build.optimization.moduleIds', () => app.store.get('build.optimization.moduleIds'))
116
- .hooks.on('build.optimization.removeEmptyChunks', () => app.store.get('build.optimization.removeEmptyChunks'))
117
- .hooks.on('build.optimization.runtimeChunk', () => app.store.is('features.runtimeChunk', true))
118
- .hooks.on('build.optimization.splitChunks', () => app.store.is('features.splitChunks', true)
119
- ? app.store.get('build.optimization.splitChunks')
120
- : undefined)
121
- /**
122
- * build.output
123
- */
39
+ .hooks.on('build.module.rules.oneOf', () => Object.values(app.build.rules).map(rule => rule.toWebpack()))
40
+ .hooks.on('build.name', app.name)
124
41
  .hooks.on('build.output', () => ({
125
42
  assetModuleFilename: app.hooks.filter('build.output.assetModuleFilename'),
126
43
  chunkFilename: app.hooks.filter('build.output.chunkFilename'),
@@ -132,79 +49,69 @@ async function build(app) {
132
49
  }))
133
50
  .hooks.on('build.output.assetModuleFilename', () => (0, filenameFormat_1.filenameFormat)(app, '[ext]'))
134
51
  .hooks.on('build.output.chunkFilename', () => (0, filenameFormat_1.filenameFormat)(app))
135
- .hooks.on('build.output.clean', () => app.store.get('build.output.clean'))
136
52
  .hooks.on('build.output.filename', () => (0, filenameFormat_1.filenameFormat)(app))
137
- .hooks.on('build.output.path', () => app.path('dist'))
138
- .hooks.on('build.output.pathinfo', () => app.store.get('build.output.pathinfo'))
139
- .hooks.on('build.output.publicPath', () => app.store.get('build.output.publicPath'))
140
- /**
141
- * Parallelism
142
- */
143
- .hooks.on('build.parallelism', () => app.store.get('build.parallelism'))
144
- /**
145
- * build.performance
146
- */
147
- .hooks.on('build.performance', () => app.store.get('build.performance'))
148
- /**
149
- * build.plugins
150
- */
53
+ .hooks.on('build.output.path', () => app.path('@dist'))
54
+ .hooks.on('build.optimization', () => ({
55
+ emitOnErrors: app.hooks.filter('build.optimization.emitOnErrors'),
56
+ minimize: app.hooks.filter('build.optimization.minimize'),
57
+ minimizer: app.hooks.filter('build.optimization.minimizer'),
58
+ moduleIds: app.hooks.filter('build.optimization.moduleIds'),
59
+ runtimeChunk: app.hooks.filter('build.optimization.runtimeChunk'),
60
+ splitChunks: app.hooks.filter('build.optimization.splitChunks'),
61
+ }))
151
62
  .hooks.async('build.plugins', async () => await app.extensions.make())
152
- /**
153
- * build.profile
154
- */
155
- .hooks.on('build.profile', () => app.store.get('build.profile'))
156
- /**
157
- * build.recordsPath
158
- */
159
- .hooks.on('build.recordsPath', () => app.path('storage', app.name, `modules.json`))
160
- /**
161
- * build.resolve
162
- */
63
+ .hooks.on('build.recordsPath', () => app.path(`@storage/${app.name}/modules.json`))
163
64
  .hooks.async('build.resolve', async () => {
164
65
  const alias = await app.hooks.filterAsync('build.resolve.alias');
165
- const extensions = app.hooks.filter('build.resolve.extensions');
66
+ const extensions = Array.from(app.hooks.filter('build.resolve.extensions'));
166
67
  const modules = await app.hooks.filterAsync('build.resolve.modules');
167
68
  return { alias, extensions, modules };
168
69
  })
169
- .hooks.async('build.resolve.alias', async () => ({}))
170
70
  .hooks.async('build.resolve.modules', async (value) => {
171
- const budPath = dirname(await bud_support_1.pkgUp.pkgUp({
172
- cwd: require.resolve('@roots/bud'),
173
- }));
174
- const peersPath = budPath
175
- .split('/')
176
- .splice(0, budPath.split('/').length - 2)
177
- .join('/');
178
- return [
179
- ...new Set([
180
- ...(value ?? []),
181
- app.hooks.filter('location.src'),
182
- app.hooks.filter('location.modules'),
183
- peersPath,
184
- ...(app.project?.get('resolve') ?? []),
185
- ...(app.root?.project.get('resolve') ?? []),
186
- ]),
187
- ];
71
+ return Array.from(new Set([
72
+ ...(value ?? []),
73
+ app.hooks.filter('location.@src'),
74
+ app.hooks.filter('location.@modules'),
75
+ ]));
188
76
  })
189
- .hooks.on('build.resolve.extensions', () => app.store.get('build.resolve.extensions'))
190
- /**
191
- * build.stats
192
- */
193
- .hooks.on('build.stats', () => app.store.get('build.stats'))
194
- /**
195
- * build.target
196
- */
197
77
  .hooks.on('build.target', () => app.project.has('manifest.browserslist') &&
198
78
  app.project.isArray('manifest.browserslist')
199
- ? `browserslist:${app.path('project', 'package.json')}`
79
+ ? `browserslist:${app.path('package.json')}`
200
80
  : undefined)
201
- /**
202
- * build.watch
203
- */
204
- .hooks.on('build.watch', () => app.store.get('build.watch'))
205
- /**
206
- * build.watchOptions
207
- */
208
- .hooks.on('build.watchOptions', () => app.store.get('build.watchOptions'));
81
+ .hooks.on('build.infrastructureLogging', () => ({
82
+ console: app.hooks.filter('build.infrastructureLogging.console'),
83
+ }));
84
+ /**
85
+ * Safe
86
+ */
87
+ app.hooks
88
+ .on('build.bail', unwrap('build.bail'))
89
+ .hooks.on('build.devtool', unwrap('build.devtool'))
90
+ .hooks.on('build.loader', unwrap('build.loader'))
91
+ .hooks.on('build.module.rules.before', unwrap('build.module.rules.before'))
92
+ .hooks.on('build.module.rules.after', unwrap('build.module.rules.after'))
93
+ .hooks.on('build.module.unsafeCache', unwrap('build.module.unsafeCache'))
94
+ .hooks.on('build.module.noParse', unwrap('build.module.noParse'))
95
+ .hooks.on('build.infrastructureLogging.level', unwrap('build.infrastructureLogging.level'))
96
+ .hooks.on('build.infrastructureLogging.console', unwrap('build.infrastructureLogging.console'))
97
+ .hooks.on('build.node', unwrap('build.node'))
98
+ .hooks.on('build.optimization.emitOnErrors', unwrap('build.optimization.emitOnErrors'))
99
+ .hooks.on('build.optimization.minimize', unwrap('build.optimization.minimize'))
100
+ .hooks.on('build.optimization.minimizer', unwrap('build.optimization.minimizer'))
101
+ .hooks.on('build.optimization.moduleIds', unwrap('build.optimization.moduleIds'))
102
+ .hooks.on('build.optimization.removeEmptyChunks', unwrap('build.optimization.removeEmptyChunks'))
103
+ .hooks.on('build.optimization.runtimeChunk', unwrap('build.optimization.runtimeChunk'))
104
+ .hooks.on('build.optimization.splitChunks', unwrap('build.optimization.splitChunks'))
105
+ .hooks.on('build.output.clean', unwrap('build.output.clean'))
106
+ .hooks.on('build.output.pathinfo', unwrap('build.output.pathinfo'))
107
+ .hooks.on('build.output.publicPath', unwrap('build.output.publicPath', 'auto'))
108
+ .hooks.on('build.parallelism', unwrap('build.parallelism'))
109
+ .hooks.on('build.performance', unwrap('build.performance'))
110
+ .hooks.on('build.profile', unwrap('build.profile'))
111
+ .hooks.async('build.resolve.alias', unwrap('build.resolve.alias'))
112
+ .hooks.on('build.resolve.extensions', unwrap('build.resolve.extensions'))
113
+ .hooks.on('build.stats', unwrap('build.stats'))
114
+ .hooks.on('build.watch', unwrap('build.watch'))
115
+ .hooks.on('build.watchOptions', unwrap('build.watchOptions'));
209
116
  }
210
117
  exports.build = build;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrap = void 0;
4
+ const bud_support_1 = require("@roots/bud-support");
5
+ const { isUndefined } = bud_support_1.lodash;
6
+ /**
7
+ * Unwrap initialValue
8
+ *
9
+ * @remarks
10
+ * Returns the initializing value for a hook
11
+ * If the value is available from {@link Framework.store}, the store value is used.
12
+ * Otherwise, it will return the fallback value (if supplied)
13
+ *
14
+ * @param this - Application
15
+ * @param key - store key
16
+ * @param fallback - fallback value
17
+ * @returns hook function
18
+ *
19
+ * @public
20
+ */
21
+ function unwrap(key, fallback) {
22
+ return (value) => {
23
+ const initValue = this.store.has(key)
24
+ ? this.maybeCall(this.store.get(key))
25
+ : value;
26
+ if (!isUndefined(initValue)) {
27
+ return initValue;
28
+ }
29
+ if (!isUndefined(fallback)) {
30
+ return fallback;
31
+ }
32
+ return undefined;
33
+ };
34
+ }
35
+ exports.unwrap = unwrap;
@@ -24,26 +24,33 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  __setModuleDefault(result, mod);
25
25
  return result;
26
26
  };
27
- var __importDefault = (this && this.__importDefault) || function (mod) {
28
- return (mod && mod.__esModule) ? mod : { "default": mod };
29
- };
30
27
  Object.defineProperty(exports, "__esModule", { value: true });
31
28
  exports.Build = void 0;
32
- const bud_framework_1 = require("@roots/bud-framework");
29
+ const Framework = __importStar(require("@roots/bud-framework"));
33
30
  const bud_support_1 = require("@roots/bud-support");
34
- const index_1 = require("../Rule/index");
35
- const config = __importStar(require("./config/index"));
36
- const items_1 = __importDefault(require("./items"));
37
- const loaders_1 = __importDefault(require("./loaders"));
31
+ const lodash_1 = require("lodash");
32
+ const Item_1 = require("../Item");
33
+ const Loader_1 = require("../Loader");
34
+ const Rule_1 = require("../Rule");
35
+ const config = __importStar(require("./config"));
36
+ const items = __importStar(require("./items"));
37
+ const loaders = __importStar(require("./loaders"));
38
38
  const rules = __importStar(require("./rules"));
39
- const { isNull, isUndefined } = bud_support_1.lodash;
39
+ const { isUndefined } = bud_support_1.lodash;
40
40
  const { ensureFile, writeFile } = bud_support_1.fs;
41
41
  /**
42
42
  * Webpack configuration builder class
43
43
  *
44
44
  * @public
45
45
  */
46
- class Build extends bud_framework_1.Service {
46
+ class Build extends Framework.Service {
47
+ constructor() {
48
+ super(...arguments);
49
+ /**
50
+ * @public
51
+ */
52
+ this.config = {};
53
+ }
47
54
  /**
48
55
  * Service booted event
49
56
  *
@@ -51,7 +58,10 @@ class Build extends bud_framework_1.Service {
51
58
  * @decorator `@bind`
52
59
  */
53
60
  async registered() {
54
- this.app.hooks.on('event.build.make.after', this.writeFinalConfig);
61
+ this.app.hooks
62
+ .action('event.build.before', async (app) => app.time(`build.make`))
63
+ .hooks.action('event.build.after', async (app) => app.timeEnd(`build.make`))
64
+ .hooks.action('event.build.after', this.writeFinalConfig);
55
65
  }
56
66
  /**
57
67
  * Make webpack configuration
@@ -60,28 +70,58 @@ class Build extends bud_framework_1.Service {
60
70
  * @decorator `@bind`
61
71
  */
62
72
  async make() {
63
- await this.app.hooks.filterAsync('event.build.make.before', this.app);
64
- const build = await this.app.hooks.filterAsync('build');
65
- if (!build) {
66
- throw new Error('Configuration could not be processed');
67
- }
68
- this.config = await this.app.hooks.filterAsync('event.build.override', Object.entries(build).reduce((all, [key, value]) => {
69
- if (isUndefined(value) || isNull(value)) {
70
- this.log(`warn`, {
71
- message: `build.make: excluding ${key}`,
72
- suffix: `value is undefined`,
73
- });
74
- return all;
75
- }
76
- this.app.dump(value, {
77
- prefix: `${bud_support_1.chalk.bgBlue(this.app.name)} config.${key}`,
78
- maxDepth: 2,
79
- });
80
- return { ...all, [key]: value };
81
- }, {}));
82
- await this.app.hooks.filterAsync('event.build.make.after', async () => null);
73
+ await this.app.hooks.fire('event.build.before');
74
+ await Promise.all([
75
+ ['entry', true],
76
+ ['plugins', true],
77
+ ['resolve', true],
78
+ ['bail'],
79
+ ['cache'],
80
+ ['context'],
81
+ ['devtool'],
82
+ ['experiments'],
83
+ ['externals'],
84
+ ['infrastructureLogging'],
85
+ ['loader'],
86
+ ['mode'],
87
+ ['module'],
88
+ ['name'],
89
+ ['node'],
90
+ ['output'],
91
+ ['optimization'],
92
+ ['parallelism'],
93
+ ['performance'],
94
+ ['profile'],
95
+ ['recordsPath'],
96
+ ['stats'],
97
+ ['target'],
98
+ ['watch'],
99
+ ['watchOptions'],
100
+ ]
101
+ .map(this.memoMap)
102
+ .filter(Boolean)
103
+ .map(this.memoMapValue));
104
+ await this.app.hooks.fire('event.build.after');
83
105
  return this.config;
84
106
  }
107
+ memoMap(...args) {
108
+ const [[key, ...rest]] = args;
109
+ if (!this.app.hooks.has(`build.${key}`))
110
+ return false;
111
+ const type = rest.length && rest.shift() ? 'async' : 'sync';
112
+ const count = this.app.hooks.count(`build.${key}`);
113
+ return [key, type, count];
114
+ }
115
+ async memoMapValue([propKey, type, _count]) {
116
+ const propValue = type == 'async'
117
+ ? await this.app.hooks.filterAsync(`build.${propKey}`)
118
+ : this.app.hooks.filter(`build.${propKey}`);
119
+ if (isUndefined(propValue))
120
+ return;
121
+ Object.assign(this.config, {
122
+ [propKey]: propValue,
123
+ });
124
+ }
85
125
  /**
86
126
  * Service register event
87
127
  *
@@ -95,7 +135,7 @@ class Build extends bud_framework_1.Service {
95
135
  });
96
136
  Object.assign(this, {
97
137
  loaders: this.app
98
- .container(loaders_1.default)
138
+ .container(loaders)
99
139
  .getEntries()
100
140
  .reduce(reducer, this.loaders),
101
141
  rules: this.app
@@ -103,7 +143,7 @@ class Build extends bud_framework_1.Service {
103
143
  .getEntries()
104
144
  .reduce(reducer, this.rules),
105
145
  items: this.app
106
- .container(items_1.default)
146
+ .container(items)
107
147
  .getEntries()
108
148
  .reduce(reducer, this.items),
109
149
  });
@@ -113,29 +153,82 @@ class Build extends bud_framework_1.Service {
113
153
  * Set a rule
114
154
  *
115
155
  * @param name - rule key
116
- * @param constructorProperties - rule constructor properties
156
+ * @param options - rule constructor properties
117
157
  * @returns the rule
118
158
  *
119
159
  * @public
120
160
  * @decorator `@bind`
121
161
  */
122
- setRule(name, constructorProperties) {
123
- Object.assign(this.rules, {
124
- [name]: this.makeRule(constructorProperties),
125
- });
126
- return this.rules[name];
162
+ setRule(name, options) {
163
+ Object.assign(this.rules, { [name]: this.makeRule(options) });
164
+ return this;
165
+ }
166
+ /**
167
+ * Make a rule
168
+ *
169
+ * @param options - rule constructor properties
170
+ * @returns the rule
171
+ *
172
+ * @public
173
+ * @decorator `@bind`
174
+ */
175
+ makeRule(options) {
176
+ return new Rule_1.Rule(() => this.app, options);
177
+ }
178
+ /**
179
+ * Set a rule
180
+ *
181
+ * @param name - rule key
182
+ * @param options - rule constructor properties
183
+ * @returns the rule
184
+ *
185
+ * @public
186
+ * @decorator `@bind`
187
+ */
188
+ setLoader(name, options) {
189
+ Object.assign(this.loaders, { [name]: this.makeLoader(options) });
190
+ return this;
191
+ }
192
+ /**
193
+ * Make a rule
194
+ *
195
+ * @param options - rule constructor properties
196
+ * @returns the rule
197
+ *
198
+ * @public
199
+ * @decorator `@bind`
200
+ */
201
+ makeLoader(options) {
202
+ return new Loader_1.Loader(() => this.app, options);
203
+ }
204
+ /**
205
+ * Set a rule
206
+ *
207
+ * @param name - rule key
208
+ * @param options - rule constructor properties
209
+ * @returns the rule
210
+ *
211
+ * @public
212
+ * @decorator `@bind`
213
+ */
214
+ setItem(name, options) {
215
+ const processedOptions = (0, lodash_1.isFunction)(options)
216
+ ? options(this.makeItem())
217
+ : this.makeItem(options);
218
+ Object.assign(this.items, { [name]: processedOptions });
219
+ return this;
127
220
  }
128
221
  /**
129
222
  * Make a rule
130
223
  *
131
- * @param constructorProperties - rule constructor properties
224
+ * @param options - rule constructor properties
132
225
  * @returns the rule
133
226
  *
134
227
  * @public
135
228
  * @decorator `@bind`
136
229
  */
137
- makeRule(constructorProperties) {
138
- return new index_1.Rule(this.app, constructorProperties);
230
+ makeItem(options) {
231
+ return new Item_1.Item(() => this.app, options);
139
232
  }
140
233
  /**
141
234
  * Write final configuration to storage directory
@@ -145,17 +238,12 @@ class Build extends bud_framework_1.Service {
145
238
  */
146
239
  async writeFinalConfig() {
147
240
  try {
148
- const filePath = this.app.path('storage', this.config.name, 'webpack.config.js');
149
- this.log('log', {
150
- message: `writing webpack dump to disk`,
151
- suffix: filePath,
152
- });
241
+ const filePath = this.app.path(`@storage/${this.config.name}/webpack.config.js`);
153
242
  await ensureFile(filePath);
154
243
  await writeFile(filePath, `module.exports = ${this.app.json.stringify(this.config, null, 2)}`);
155
244
  }
156
245
  catch (error) {
157
- this.log('error', `failed to write webpack.config.json`);
158
- this.log(`error`, error);
246
+ this.app.error(`failed to write webpack.config.json`);
159
247
  }
160
248
  }
161
249
  }
@@ -165,6 +253,13 @@ __decorate([
165
253
  __decorate([
166
254
  bud_support_1.bind
167
255
  ], Build.prototype, "make", null);
256
+ __decorate([
257
+ bud_support_1.bind
258
+ ], Build.prototype, "memoMap", null);
259
+ __decorate([
260
+ bud_support_1.bind,
261
+ (0, bud_support_1.memo)()
262
+ ], Build.prototype, "memoMapValue", null);
168
263
  __decorate([
169
264
  bud_support_1.bind
170
265
  ], Build.prototype, "register", null);
@@ -174,6 +269,18 @@ __decorate([
174
269
  __decorate([
175
270
  bud_support_1.bind
176
271
  ], Build.prototype, "makeRule", null);
272
+ __decorate([
273
+ bud_support_1.bind
274
+ ], Build.prototype, "setLoader", null);
275
+ __decorate([
276
+ bud_support_1.bind
277
+ ], Build.prototype, "makeLoader", null);
278
+ __decorate([
279
+ bud_support_1.bind
280
+ ], Build.prototype, "setItem", null);
281
+ __decorate([
282
+ bud_support_1.bind
283
+ ], Build.prototype, "makeItem", null);
177
284
  __decorate([
178
285
  bud_support_1.bind
179
286
  ], Build.prototype, "writeFinalConfig", null);