Skip to content

Commit

Permalink
🏗 Push shared dependencies into bento.js
Browse files Browse the repository at this point in the history
  • Loading branch information
alanorozco committed Oct 27, 2021
1 parent 30413cf commit 84708c9
Show file tree
Hide file tree
Showing 36 changed files with 510 additions and 37 deletions.
2 changes: 2 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ const babelTransforms = new Map([
['babel-jest', 'getEmptyConfig'],
['post-closure', 'getPostClosureConfig'],
['pre-closure', 'getPreClosureConfig'],
['bento-pre-closure', 'getBentoPreClosureConfig'],
['test', 'getTestConfig'],
['unminified', 'getUnminifiedConfig'],
['bento-unminified', 'getBentoUnminifiedConfig'],
['minified', 'getMinifiedConfig'],
['jss', 'getJssConfig'],
['@babel/eslint-parser', 'getEslintConfig'],
Expand Down
19 changes: 19 additions & 0 deletions build-system/babel-config/bento-pre-closure-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const {getPreClosureConfig} = require('./pre-closure-config');

/**
* @return {!Object}
*/
function getBentoPreClosureConfig() {
const config = getPreClosureConfig();
return {
...config,
plugins: [
'./build-system/babel-plugins/babel-plugin-bento-imports',
...config.plugins,
],
};
}

module.exports = {
getBentoPreClosureConfig,
};
19 changes: 19 additions & 0 deletions build-system/babel-config/bento-unminified-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const {getUnminifiedConfig} = require('./unminified-config');

/**
* @return {!Object}
*/
function getBentoUnminifiedConfig() {
const config = getUnminifiedConfig();
return {
...config,
plugins: [
'./build-system/babel-plugins/babel-plugin-bento-imports',
...config.plugins,
],
};
}

module.exports = {
getBentoUnminifiedConfig,
};
95 changes: 95 additions & 0 deletions build-system/babel-plugins/babel-plugin-bento-imports/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* @fileoverview
* Replaces `import` statements of listed modules with `const` statements.
* These reference the global `BENTO` which is meant to provide the contents of
* these listed modules.
*/

const bentoRuntimePackages = require('../../compile/generate/metadata/bento-runtime-packages');

module.exports = function (babel) {
const {types: t} = babel;

/**
* @param {babel.NodePath} path
* @return {babel.NodePath}
*/
function getLastInSequenceOfType(path) {
let last = path;
while (
typeof last.key === 'number' &&
path.getSibling(last.key + 1).node?.type === last.node.type
) {
last = path.getSibling(last.key + 1);
}
return last;
}

const visitor = {
ImportDeclaration(path, state) {
// Options for tests
const packages = state.opts.packages || bentoRuntimePackages;

const source = path.node.source.value;
const names = packages[source];
if (!names) {
return;
}

const preservedSpecifiers = [];
const statements = path.node.specifiers.map((node) => {
// Full object reference for namespace imports
// - import * as p from 'package';
// + const p = {'x': BENTO['package']['x'], ...}
if (t.isImportNamespaceSpecifier(node)) {
const properties = names
.map((name) => `'${name}': PKG['${name}']`)
.join(',');
return `const ${node.local.name} = {${properties}}`;
}
// One statement per named import
// - import {z, y} from 'package';
// + const z = BENTO['package']['z'];
// + const y = BENTO['package']['y'];
if (t.isImportSpecifier(node) && names.includes(node.imported.name)) {
return `const ${node.local.name} = PKG['${node.imported.name}']`;
}
preservedSpecifiers.push(node);
});

if (preservedSpecifiers.length === path.node.specifiers.length) {
// all preserved, nothing to do
return;
}

const template = statements.filter(Boolean).join(';\n');

const declaration = babel.template(template)({
// We need to specify a placeholder key because babel's `template` will
// fail with unspecified UPPERCASE identifiers.
'PKG': `BENTO[${JSON.stringify(source)}]`,
});

// Insert below this sequence of ImportDeclarations
getLastInSequenceOfType(path).insertAfter(declaration);

if (preservedSpecifiers.length === 0) {
path.remove();
} else {
path.node.specifiers = preservedSpecifiers;
}
},
};

return {
name: 'bento-imports',
visitor: {
// We visit on Program.enter to take priority over module-resolver
Program: {
enter(programPath, state) {
programPath.traverse(visitor, state);
},
},
},
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import {ignored} from './unlisted';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"plugins": [
[
"../../../..",
{
"packages": {
"~foo": [
"a",
"b",
"c"
],
"~bar/baz": [
"fooBar"
]
}
}
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { ignored } from './unlisted';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import {a, b, c as x} from '~foo';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"plugins": [
[
"../../../..",
{
"packages": {
"~foo": [
"a",
"b",
"c"
],
"~bar/baz": [
"fooBar"
]
}
}
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const a = BENTO["~foo"]['a'];
const b = BENTO["~foo"]['b'];
const x = BENTO["~foo"]['c'];
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as foo from '~foo';
import {fooBar, __unlistedShouldBePreserved} from '~bar/baz';
import {ignored} from './unlisted';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"plugins": [
[
"../../../..",
{
"packages": {
"~foo": [
"a",
"b",
"c"
],
"~bar/baz": [
"fooBar"
]
}
}
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { __unlistedShouldBePreserved } from '~bar/baz';
import { ignored } from './unlisted';
const fooBar = BENTO["~bar/baz"]['fooBar'];
const foo = {
'a': BENTO["~foo"]['a'],
'b': BENTO["~foo"]['b'],
'c': BENTO["~foo"]['c']
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import * as foo from '~foo';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"plugins": [
[
"../../../..",
{
"packages": {
"~foo": [
"a",
"b",
"c"
],
"~bar/baz": [
"fooBar"
]
}
}
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const foo = {
'a': BENTO["~foo"]['a'],
'b': BENTO["~foo"]['b'],
'c': BENTO["~foo"]['c']
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import {a, __unlistedShouldBePreserved} from '~foo';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"plugins": [
[
"../../../..",
{
"packages": {
"~foo": [
"a",
"b",
"c"
],
"~bar/baz": [
"fooBar"
]
}
}
]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { __unlistedShouldBePreserved } from '~foo';
const a = BENTO["~foo"]['a'];
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const runner = require('@babel/helper-plugin-test-runner').default;

runner(__dirname);
4 changes: 3 additions & 1 deletion build-system/compile/bundles.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ exports.jsBundles = {
minifiedDestDir: './build/',
},
'bento.js': {
srcDir: './src/',
// This file is generated, so we find its source in the build/ dir
// See compileBentoRuntime() and generateBentoRuntime()
srcDir: 'build/',
srcFilename: 'bento.js',
destDir: './dist',
minifiedDestDir: './dist',
Expand Down
6 changes: 5 additions & 1 deletion build-system/compile/closure-compile.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const compiler = require('@ampproject/google-closure-compiler');
const path = require('path');
const vinylFs = require('vinyl-fs');
const {cyan, red, yellow} = require('kleur/colors');
const {getBabelOutputDir} = require('./pre-closure-babel');
Expand Down Expand Up @@ -77,8 +78,11 @@ function initializeClosure(flags, options) {
*/
function runClosure(outputFilename, options, flags, srcFiles) {
return new Promise((resolve, reject) => {
// We use a different babel configuration for bento-* files, so its
// transforms are in a subdirectory.
const base = path.join(getBabelOutputDir(), options.bento ? 'bento' : '');
vinylFs
.src(srcFiles, {base: getBabelOutputDir()})
.src(srcFiles, {base})
.pipe(initializeClosure(flags, options))
.on('error', (err) => {
const reason = handleClosureCompilerError(err, outputFilename, options);
Expand Down
3 changes: 3 additions & 0 deletions build-system/compile/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ function getSrcs(entryModuleFilenames, options) {
.split(path.win32.sep)
.join(path.posix.sep)
);
} else {
// Ensure that entrypoint itself is listed.
srcs.push(filename);
}
});
if (options.extraGlobs) {
Expand Down
14 changes: 14 additions & 0 deletions build-system/compile/generate/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// For an explanation of the OWNERS rules and syntax, see:
// https://github.com/ampproject/amp-github-apps/blob/main/owners/OWNERS.example

{
rules: [
{
owners: [
{name: 'ampproject/wg-infra'},
{name: 'ampproject/wg-bento'},
{name: 'alanorozco', notify: true},
],
},
],
}
Loading

0 comments on commit 84708c9

Please sign in to comment.