Skip to content

Commit

Permalink
Work on stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
thecrypticace committed Oct 21, 2021
1 parent 1b52409 commit e2c83cc
Show file tree
Hide file tree
Showing 13 changed files with 589 additions and 656 deletions.
26 changes: 9 additions & 17 deletions src/Build/BuildContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ const { Manifest } = require('./Manifest');
*/
exports.BuildContext = class BuildContext {
/**
* @param {import('../Mix')} mix
* @param {import('./BuildGroup').BuildGroup} group
*/
constructor(mix) {
constructor(group) {
/** @internal */
this.mix = mix;
this.group = group;

/**
* @public
* @type {typeof mix.config}
* @type {typeof group.mix.config}
*/
this.config = Object.create(mix.config);
this.config = Object.create(group.mix.config);

/**
* @public
*/
this.chunks = new Chunks(mix);
this.chunks = new Chunks(group.mix);

/**
* @public
*/
this.manifest = new Manifest();

/**
* @type {Task[]}
* @type {Task<any>[]}
* @internal
**/
this.tasks = [];
Expand All @@ -47,7 +47,7 @@ exports.BuildContext = class BuildContext {
* Queue up a new task.
* TODO: Add a "stage" to tasks so they can run at different points during the build
*
* @param {Task} task
* @param {Task<any>} task
* @param {{ when: "before" | "during" | "after"}} options
*/
addTask(task, options) {
Expand All @@ -58,14 +58,6 @@ exports.BuildContext = class BuildContext {
* @returns {import("../../types/index")}
*/
get api() {
if (!this._api) {
this._api = this.mix.registrar.installAll();

// @ts-ignore
this._api.inProduction = () => this.config.production;
}

// @ts-ignore
return this._api;
return this.group.components.api;
}
};
9 changes: 7 additions & 2 deletions src/Build/BuildGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ exports.BuildGroup = class BuildGroup {
this.name = name;
this.mix = mix;
this.callback = callback;
this.context = new BuildContext(mix);
this.context = new BuildContext(this);
this.components = mix.registrar;
}

/**
Expand All @@ -47,7 +48,11 @@ exports.BuildGroup = class BuildGroup {
* @internal
*/
async setup() {
return this.whileCurrent(() => this.callback(this.context.api, this.context));
return this.whileCurrent(() => {
this.components.installAll();

return this.callback(this.context.api, this.context);
});
}

/**
Expand Down
163 changes: 163 additions & 0 deletions src/Build/ComponentInstance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
const { concat, extend } = require('lodash');
const Dependencies = require('../Dependencies');

/**
* @typedef {import('../../types/component').ComponentInterface} ComponentInterface
* @typedef {import('../../types/component').InstallableComponent} InstallableComponent
* @typedef {import('../../types/component').Component} Component
**/

/**
* @template TArgs
*
* @typedef {object} ComponentInvocation
* @property {string} name
* @property {TArgs} args
**/

/** @private */
module.exports.ComponentInstance = class ComponentInstance {
/** @type {'installed' | 'active'} */
state = 'installed';

/**
* @param {import("./BuildGroup").BuildGroup} group
* @param {ComponentInterface} instance
*/
constructor(group, instance) {
this.group = group;
this.instance = instance;
}

/**
* @internal
* @param {ComponentInvocation<any[]>} invocation
* @returns
*/
run(invocation) {
const { name, args } = invocation;

// Legacy support
if (this.group.name === 'default') {
this.mix.components.record(name, this.instance);
}

this.state = 'active';

// @ts-ignore
this.instance.caller = name;

this.instance.register && this.instance.register(...args);

// @ts-ignore
this.instance.activated = true;
}

/**
* @returns
*/
async collectDeps() {
if (this.state !== 'active') {
return;
}

/** @type {import('../Dependencies').Dependency[]} */
const deps = this.instance.dependencies
? concat([], await this.instance.dependencies())
: [];

Dependencies.queue(deps, this.instance.requiresReload || false);
}

/**
* @returns
*/
async init() {
if (this.state !== 'active') {
return;
}

await this.boot();
await this.applyBabelConfig();

this.mix.listen('loading-entry', entry => this.applyEntry(entry));
this.mix.listen('loading-rules', rules => this.applyRules(rules));
this.mix.listen('loading-plugins', plugins => this.applyPlugins(plugins));
this.mix.listen('configReady', config => this.applyConfig(config));
}

/**
* Apply the Babel configuration for the component.
*
* @private
*/
async boot() {
this.instance.boot && (await this.instance.boot());
}

/**
* Apply the Babel configuration for the component.
*
* @private
*/
async applyBabelConfig() {
const config = this.instance.babelConfig
? (await this.instance.babelConfig()) || {}
: {};

this.group.context.config.merge({
babelConfig: extend(this.group.context.config.babelConfig, config)
});
}

/**
* Apply the Babel configuration for the component.
*
* @param {import('../builder/Entry')} entry
*/
async applyEntry(entry) {
return this.instance.webpackEntry && this.instance.webpackEntry(entry);
}

/**
* Apply the webpack rules for the component.
*
* @param {import('webpack').RuleSetRule[]} rules
* @private
*/
async applyRules(rules) {
const newRules = this.instance.webpackRules
? concat((await this.instance.webpackRules()) || [])
: [];

rules.push(...newRules);
}

/**
* Apply the webpack plugins for the component.
*
* @param {import('webpack').WebpackPluginInstance[]} plugins
* @private
*/
async applyPlugins(plugins) {
const newPlugins = this.instance.webpackPlugins
? concat((await this.instance.webpackPlugins()) || [])
: [];

plugins.push(...newPlugins);
}

/**
* Apply the webpack plugins for the component.
*
* @param {import('webpack').Configuration} config
* @private
*/
async applyConfig(config) {
return this.instance.webpackConfig && this.instance.webpackConfig(config);
}

get mix() {
return this.group.mix;
}
};

0 comments on commit e2c83cc

Please sign in to comment.