From 4bcc6c7e17be6ddcd721a0e5619eaa874a2a5cf0 Mon Sep 17 00:00:00 2001 From: Kris Selden Date: Thu, 14 Dec 2017 17:13:21 -0800 Subject: [PATCH] Make yarn link of glimmer easier. Build is based on entry point, and the yarn link script links any linked glimmer module. --- bin/yarn-link-glimmer.js | 31 +++-------------- broccoli/find-lib.js | 16 ++------- broccoli/find-package.js | 52 ++++++++++++++++++++++++++++ broccoli/packages.js | 73 ++++++++++++++++++++++++++++++++-------- ember-cli-build.js | 34 +++---------------- 5 files changed, 124 insertions(+), 82 deletions(-) create mode 100644 broccoli/find-package.js diff --git a/bin/yarn-link-glimmer.js b/bin/yarn-link-glimmer.js index 557269bcdff..4daf1551878 100755 --- a/bin/yarn-link-glimmer.js +++ b/bin/yarn-link-glimmer.js @@ -1,31 +1,10 @@ #!/usr/bin/env node "use strict"; const child_process = require("child_process"); -const glimmerDeps = []; -addGlimmerPackageDeps(require("../package"), true); +const yarnConfig = JSON.parse(JSON.parse(require('child_process').execSync('yarn --json config current', { encoding: 'utf8' })).data); +const linkedModules = yarnConfig.linkedModules.filter((m) => m.startsWith('@glimmer/')); -function linkGlimmerDep(glimmerDep) { - if (glimmerDeps.indexOf(glimmerDep) === -1) { - glimmerDeps.push(glimmerDep); - console.log(glimmerDep); - child_process.execSync(`yarn link "${glimmerDep}"`); - addGlimmerPackageDeps(require(`${glimmerDep}/package`), false); - } -} - -function addGlimmerDeps(dependencies) { - if (!dependencies) return; - Object.keys(dependencies).forEach(dep => { - if (dep.lastIndexOf("@glimmer", 0) === 0) { - linkGlimmerDep(dep); - } - }); -} - -function addGlimmerPackageDeps(packageJson, dev) { - addGlimmerDeps(packageJson["dependencies"]); - if (dev) { - addGlimmerDeps(packageJson["devDependencies"]); - } -} +linkedModules.forEach(mod => { + child_process.execSync(`yarn link "${mod}"`); +}); diff --git a/broccoli/find-lib.js b/broccoli/find-lib.js index 9e473ffe227..de4169fc679 100644 --- a/broccoli/find-lib.js +++ b/broccoli/find-lib.js @@ -1,19 +1,9 @@ /* eslint-env node */ "use strict"; - const path = require('path'); +const findPackage = require('./find-package'); module.exports = function findLib(name, libPath) { - let packagePath = path.join(name, 'package'); - let packageRoot = path.dirname(require.resolve(packagePath)); - - libPath = libPath || getLibPath(packagePath); - - return path.resolve(packageRoot, libPath); + let pkg = findPackage(name); + return pkg.resolve(libPath) || (pkg.module || pkg.main).dir; }; - -function getLibPath(packagePath) { - let packageJson = require(packagePath); - - return path.dirname(packageJson['module'] || packageJson['main']); -} \ No newline at end of file diff --git a/broccoli/find-package.js b/broccoli/find-package.js new file mode 100644 index 00000000000..07251bc6526 --- /dev/null +++ b/broccoli/find-package.js @@ -0,0 +1,52 @@ +"use strict"; +const path = require('path'); + +const cache = new Map(); + +module.exports = function findPackage(name) { + let info = cache.get(name); + if (info === undefined) { + info = new PackageInfo(name); + cache.set(name, info); + } + return info; +}; + +class PackageInfo { + constructor(name) { + this.name = name; + let pkgName = name + '/package'; + let config = require(pkgName); + this.config = config; + this.dir = path.dirname(require.resolve(pkgName)); + } + + get main() { + return this.parseResolve(this.config.main); + } + + get module() { + return this.parseResolve(this.config.module); + } + + get dependencies() { + return this.config.dependencies && Object.keys(this.config.dependencies); + } + + resolve(relative) { + if (!relative) return; + return path.resolve(this.dir, relative); + } + + parseResolve(relative) { + if (!relative) return; + let resolved = this.resolve(relative); + let parsed = path.parse(resolved); + return { + dir: parsed.dir, + base: parsed.base, + path: resolved, + }; + } + +} diff --git a/broccoli/packages.js b/broccoli/packages.js index 9cbc1b6f19f..aafa3f20aaf 100644 --- a/broccoli/packages.js +++ b/broccoli/packages.js @@ -1,12 +1,13 @@ 'use strict'; /* eslint-env node */ -const { readFileSync } = require('fs'); +const { readFileSync, existsSync } = require('fs'); const path = require('path'); const Rollup = require('broccoli-rollup'); const Funnel = require('broccoli-funnel'); const filterTypeScript = require('broccoli-typescript-compiler').filterTypeScript; const BroccoliDebug = require('broccoli-debug'); const findLib = require('./find-lib'); +const findPackage = require('./find-package'); const funnelLib = require('./funnel-lib'); const { VERSION } = require('./version'); const WriteFile = require('broccoli-file-creator'); @@ -169,7 +170,6 @@ module.exports.routeRecognizerES = function _routeRecognizerES() { }); } - module.exports.simpleHTMLTokenizerES = function _simpleHTMLTokenizerES() { return new Rollup(findLib('simple-html-tokenizer', 'dist/es6'), { annotation: 'simple-html-tokenizer es', @@ -207,19 +207,64 @@ module.exports.emberPkgES = function _emberPkgES(name, rollup, externs) { }); } -module.exports.glimmerPkgES = function _glimmerPkgES(name, externs = []) { - return new Rollup(findLib(name, 'dist/modules/es5'), { - annotation: `${name} es`, - rollup: { - input: 'index.js', - external: externs, - output: { - file: `${name}.js`, - format: 'es', - exports: 'named' - } +const glimmerTrees = new Map(); + +function rollupGlimmerPackage(pkg, deps) { + let name = pkg.name; + let tree = glimmerTrees.get(name); + if (tree === undefined) { + tree = new Rollup(pkg.module.dir, { + rollup: { + input: pkg.module.base, + external: pkg.dependencies, + output: { + file: name + '.js', + format: 'es' + }, + }, + annotation: name + }); + glimmerTrees.set(name, tree); + } + return tree; +} + +module.exports.glimmerPkgES = function glimmerPkgES(name) { + return rollupGlimmerPackage(findPackage(name)); +} + +module.exports.glimmerTrees = function glimmerTrees(entries) { + let seen = new Set(); + + // glimmer runtime has dependency on this even though it is only in tests + seen.add('@glimmer/object'); + seen.add('@glimmer/object-reference'); + + let trees = []; + let queue = Array.isArray(entries) ? entries.slice() : [ entries ]; + let name; + while ((name = queue.pop()) !== undefined) { + if (seen.has(name)) { + continue; } - }); + seen.add(name); + + if (!name.startsWith('@glimmer/')) { + continue; + } + + let pkg = findPackage(name); + + if (pkg.module && existsSync(pkg.module.path)) { + trees.push(rollupGlimmerPackage(pkg)); + } + + let dependencies = pkg.dependencies; + if (dependencies) { + queue.push(...dependencies); + } + } + return trees; } module.exports.emberTestsES = function _emberTestES(name) { diff --git a/ember-cli-build.js b/ember-cli-build.js index d51fa4a89b2..2ab778611c2 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -32,7 +32,7 @@ const { dagES, routeRecognizerES, emberPkgES, - glimmerPkgES, + glimmerTrees, emberTestsES, nodeModuleUtils, emberVersionES, @@ -57,17 +57,7 @@ module.exports = function(options) { let emberDebugES5 = toES5(emberDebug, { annotation: 'ember-debug' }); let emberTemplateCompiler = emberPkgES('ember-template-compiler'); let emberTemplateCompilerES5 = toES5(emberTemplateCompiler, { annotation: 'ember-template-compiler' }); - let glimmerSyntax = toES5( - glimmerPkgES('@glimmer/syntax', ['@glimmer/util', 'handlebars', 'simple-html-tokenizer']), - { annotation: '@glimmer/syntax' } - ); - let glimmerCompiler = toES5( - glimmerPkgES('@glimmer/compiler', ['@glimmer/util', '@glimmer/wire-format', '@glimmer/syntax']), - { annotation: '@glimmer/compiler' } - ); - let glimmerReference = toES5(glimmerPkgES('@glimmer/reference', ['@glimmer/util'])); - let glimmerUtil = toES5(glimmerPkgES('@glimmer/util')); - let glimmerWireFormat = toES5(glimmerPkgES('@glimmer/wire-format', ['@glimmer/util'])); + let babelDebugHelpersES5 = toES5(babelHelpers('debug'), { annotation: 'babel helpers debug' }); let inlineParser = toES5(handlebarsES(), { annotation: 'handlebars' }); let tokenizer = toES5(simpleHTMLTokenizerES(), { annotation: 'tokenizer' }); @@ -136,9 +126,6 @@ module.exports = function(options) { emberMetalES5, emberConsoleES5, emberDebugES5, - glimmerReference, - glimmerUtil, - glimmerWireFormat, backburner, version, license, @@ -195,11 +182,8 @@ module.exports = function(options) { emberConsoleES5, emberTemplateCompilerES5, emberDebugES5, - glimmerSyntax, - glimmerCompiler, - glimmerReference, - glimmerUtil, - glimmerWireFormat, + // metal depends on @glimmer/reference + ...glimmerTrees(['@glimmer/compiler', '@glimmer/reference']).map(toES5), backburner, debugFeatures, tokenizer, @@ -229,9 +213,6 @@ module.exports = function(options) { }); let depsProd = [ - glimmerReference, - glimmerUtil, - glimmerWireFormat, backburner, rsvp ].map(stripForProd); @@ -342,12 +323,7 @@ function dependenciesES6() { dagES(), routerES(), routeRecognizerES(), - glimmerPkgES('@glimmer/node', ['@glimmer/runtime']), - glimmerPkgES('@glimmer/runtime', [ - '@glimmer/util', - '@glimmer/reference', - '@glimmer/wire-format' - ]) + ...glimmerTrees(['@glimmer/node', '@glimmer/runtime']), ]; }