mirror of
https://github.com/fleetbase/fleetbase.git
synced 2025-12-19 14:18:57 +00:00
fix: Correct Broccoli plugin wiring to merge into app.trees.app
- Merge generatedAppTree into app.trees.app before app.toTree() - Fix Funnel srcDir/destDir configuration - Remove prebuild extension generation (now handled by Broccoli) - Add extensionManifestTree to expose dist/extensions.json - Files now treated as real app source for ember-auto-import
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
||||
const Funnel = require('broccoli-funnel');
|
||||
const writeFile = require('broccoli-file-creator');
|
||||
const mergeTrees = require('broccoli-merge-trees');
|
||||
const postcssImport = require('postcss-import');
|
||||
const postcssPresetEnv = require('postcss-preset-env');
|
||||
const postcssEach = require('postcss-each');
|
||||
@@ -15,6 +16,12 @@ const tailwind = require('tailwindcss');
|
||||
const toBoolean = require('./config/utils/to-boolean');
|
||||
const environment = process.env.EMBER_ENV;
|
||||
|
||||
// Import Broccoli plugins
|
||||
const ExtensionDiscoveryPlugin = require('./lib/build-plugins/extension-discovery');
|
||||
const ExtensionShimGeneratorPlugin = require('./lib/build-plugins/extension-shim-generator');
|
||||
const ExtensionLoadersGeneratorPlugin = require('./lib/build-plugins/extension-loaders-generator');
|
||||
const RouterGeneratorPlugin = require('./lib/build-plugins/router-generator');
|
||||
|
||||
module.exports = function (defaults) {
|
||||
const app = new EmberApp(defaults, {
|
||||
storeConfigInMeta: false,
|
||||
@@ -68,7 +75,92 @@ module.exports = function (defaults) {
|
||||
},
|
||||
});
|
||||
|
||||
// Extension shims are generated by prebuild.js before ember build
|
||||
// Step 1: Create extension discovery and generator instances
|
||||
const extensionDiscovery = new ExtensionDiscoveryPlugin([], {
|
||||
projectRoot: __dirname,
|
||||
annotation: "Discover Fleetbase Extensions",
|
||||
});
|
||||
|
||||
const extensionShims = new ExtensionShimGeneratorPlugin([extensionDiscovery], {
|
||||
projectRoot: __dirname,
|
||||
annotation: "Generate Extension Shims",
|
||||
});
|
||||
|
||||
const extensionLoaders = new ExtensionLoadersGeneratorPlugin([extensionDiscovery], {
|
||||
projectRoot: __dirname,
|
||||
annotation: "Generate Extension Loaders",
|
||||
});
|
||||
|
||||
const router = new RouterGeneratorPlugin([extensionDiscovery], {
|
||||
projectRoot: __dirname,
|
||||
annotation: "Generate Router with Extension Mounts",
|
||||
});
|
||||
|
||||
// Step 2: Build a "generated app" tree
|
||||
// The plugin outputs currently contain files relative to their own outputPath:
|
||||
// - extensionShims output: extensions/*.js
|
||||
// - extensionLoaders output: utils/extension-loaders.generated.js
|
||||
// - router output: router.js
|
||||
//
|
||||
// We want these to appear in the app source tree as:
|
||||
// - app/extensions/*.js
|
||||
// - app/utils/extension-loaders.generated.js
|
||||
// - app/router.js
|
||||
//
|
||||
// To achieve this, we build a merged tree whose paths mirror app/ structure:
|
||||
const generatedAppTree = mergeTrees(
|
||||
[
|
||||
// app/extensions/*.js
|
||||
// extensionShims writes to outputPath/extensions/*.js
|
||||
// We want these files at app/extensions/*.js in the final tree
|
||||
new Funnel(extensionShims, {
|
||||
srcDir: "extensions",
|
||||
destDir: "extensions",
|
||||
}),
|
||||
|
||||
// app/utils/extension-loaders.generated.js
|
||||
// extensionLoaders writes to outputPath/utils/*.js
|
||||
new Funnel(extensionLoaders, {
|
||||
srcDir: "utils",
|
||||
destDir: "utils",
|
||||
}),
|
||||
|
||||
// app/router.js
|
||||
// router writes to outputPath/router.js
|
||||
new Funnel(router, {
|
||||
srcDir: "/",
|
||||
destDir: "/",
|
||||
}),
|
||||
],
|
||||
{
|
||||
overwrite: true,
|
||||
annotation: "Merge Extension Generated Files into app tree",
|
||||
}
|
||||
);
|
||||
|
||||
// Step 3: Merge generatedAppTree into app.trees.app
|
||||
// Before calling app.toTree(), we must ensure that app.trees.app includes the generated files.
|
||||
app.trees.app = mergeTrees(
|
||||
[app.trees.app, generatedAppTree],
|
||||
{ overwrite: true }
|
||||
);
|
||||
|
||||
// This makes Ember treat the generated files as if they had been in the app/ directory from the beginning.
|
||||
|
||||
// Step 4: Expose extensions.json as dist/extensions.json
|
||||
// We also want the discovery manifest to be accessible at dist/extensions.json. To do this, we
|
||||
// funnel the discovery plugin output:
|
||||
const extensionManifestTree = new Funnel(extensionDiscovery, {
|
||||
srcDir: "/",
|
||||
files: ["extensions.json"],
|
||||
destDir: "/",
|
||||
});
|
||||
|
||||
// Now, extensionManifestTree will place extensions.json at the root of the final dist output.
|
||||
|
||||
// Step 5: Final app.toTree() call
|
||||
// Instead of passing the "extensions" tree into app.toTree(), we now pass only the trees that
|
||||
// represent additional *top-level* output (such as the manifest and runtimeConfigTree).
|
||||
|
||||
// Runtime config
|
||||
let runtimeConfigTree;
|
||||
@@ -81,5 +173,7 @@ module.exports = function (defaults) {
|
||||
});
|
||||
}
|
||||
|
||||
return app.toTree([runtimeConfigTree].filter(Boolean));
|
||||
return app.toTree(
|
||||
[extensionManifestTree, runtimeConfigTree].filter(Boolean)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -173,62 +173,4 @@ function getRouterFileContents() {
|
||||
|
||||
const output = recast.print(ast, { quote: 'single' }).code;
|
||||
fs.writeFileSync(path.join(__dirname, 'app/router.js'), output);
|
||||
|
||||
// Generate extension shims
|
||||
console.log('[Prebuild] Generating extension shims...');
|
||||
generateExtensionShims(extensions);
|
||||
})();
|
||||
|
||||
function generateExtensionShims(extensions) {
|
||||
const extensionsDir = path.join(__dirname, 'app', 'extensions');
|
||||
const utilsDir = path.join(__dirname, 'app', 'utils');
|
||||
|
||||
// Create directories
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
fs.mkdirSync(utilsDir, { recursive: true });
|
||||
|
||||
const loaderEntries = [];
|
||||
|
||||
// Generate shim for each extension that has extension.js
|
||||
for (const extension of extensions) {
|
||||
const extensionPath = path.join(__dirname, 'node_modules', extension.name, 'addon', 'extension.js');
|
||||
|
||||
if (fs.existsSync(extensionPath)) {
|
||||
try {
|
||||
// Read the extension code
|
||||
const extensionCode = fs.readFileSync(extensionPath, 'utf8');
|
||||
|
||||
// Generate shim content
|
||||
const shimContent = `// AUTO-GENERATED - DO NOT EDIT
|
||||
// Extension shim for ${extension.name}
|
||||
${extensionCode}
|
||||
`;
|
||||
|
||||
// Write shim file
|
||||
const mountName = getExtensionMountPath(extension.name);
|
||||
const shimPath = path.join(extensionsDir, `${mountName}.js`);
|
||||
fs.writeFileSync(shimPath, shimContent, 'utf8');
|
||||
|
||||
// Add to loader map
|
||||
loaderEntries.push(` '${extension.name}': () => import('@fleetbase/console/extensions/${mountName}')`);
|
||||
|
||||
console.log(`[Prebuild] ✓ Generated shim: app/extensions/${mountName}.js`);
|
||||
} catch (error) {
|
||||
console.error(`[Prebuild] Failed to generate shim for ${extension.name}:`, error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate extension loaders file
|
||||
const loadersContent = `// AUTO-GENERATED - DO NOT EDIT
|
||||
// Extension loader map for dynamic imports
|
||||
export const EXTENSION_LOADERS = {
|
||||
${loaderEntries.join(',\n')}
|
||||
};
|
||||
`;
|
||||
|
||||
const loadersPath = path.join(utilsDir, 'extension-loaders.js');
|
||||
fs.writeFileSync(loadersPath, loadersContent, 'utf8');
|
||||
|
||||
console.log(`[Prebuild] ✓ Generated ${loaderEntries.length} extension shims and loader map`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user