Skip to content

Commit 991b44b

Browse files
authored
♻️ 🏗 Update build-system to build bento components stored in a new directory (ampproject#36639)
* update build-system to build bento components stored in a new directory and move jwplayer
1 parent 2c41c95 commit 991b44b

27 files changed

+594
-41
lines changed

Diff for: .eslintrc.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ module.exports = {
355355
'test/**/*.js',
356356
'extensions/**/test/**/*.js',
357357
'extensions/**/test-e2e/*.js',
358+
'src/bento/components/**/test/**/*.js',
359+
'src/bento/components/**/test-e2e/*.js',
358360
'ads/**/test/**/*.js',
359361
'testing/**/*.js',
360362
'build-system/**/test/*.js',
@@ -462,7 +464,12 @@ module.exports = {
462464
'rules': {'import/order': 0},
463465
},
464466
{
465-
'files': ['src/preact/**', 'extensions/**/1.0/**', '**/storybook/**'],
467+
'files': [
468+
'extensions/**/1.0/**',
469+
'src/bento/**',
470+
'src/preact/**',
471+
'**/storybook/**',
472+
],
466473
'rules': {'local/preact-preferred-props': 2},
467474
},
468475
{

Diff for: build-system/babel-config/test-config.js

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function getTestConfig() {
1717
'ads/**/*.js',
1818
'build-system/**/*.js',
1919
'extensions/**/test/**/*.js',
20+
'src/bento/components/**/test/**/*.js',
2021
'third_party/**/*.js',
2122
'test/**/*.js',
2223
'testing/**/*.js',

Diff for: build-system/compile/bundles.config.bento.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"name": "jwplayer",
4+
"version": "1.0",
5+
"options": {}
6+
}
7+
]

Diff for: build-system/compile/bundles.config.extensions.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,7 @@
613613
"version": "1.0",
614614
"latestVersion": "0.1",
615615
"options": {
616-
"hasCss": true,
617-
"bento": true,
618-
"npm": true
616+
"hasCss": true
619617
}
620618
},
621619
{

Diff for: build-system/compile/bundles.config.js

+33
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
'use strict';
2+
const bentoBundles = require('./bundles.config.bento.json');
23
const extensionBundles = require('./bundles.config.extensions.json');
34
const wrappers = require('./compile-wrappers');
45
const {cyan, red} = require('kleur/colors');
@@ -206,6 +207,11 @@ exports.jsBundles = {
206207
*/
207208
exports.extensionBundles = extensionBundles;
208209

210+
/**
211+
* Used to generate component build targets
212+
*/
213+
exports.bentoBundles = bentoBundles;
214+
209215
/**
210216
* Used to alias a version of an extension to an older deprecated version.
211217
*/
@@ -260,3 +266,30 @@ exports.verifyExtensionBundles = function () {
260266
);
261267
});
262268
};
269+
270+
exports.verifyBentoBundles = function () {
271+
bentoBundles.forEach((bundle, i) => {
272+
const bundleString = JSON.stringify(bundle, null, 2);
273+
verifyBundle_(
274+
'name' in bundle,
275+
'name',
276+
'is missing from',
277+
'',
278+
bundleString
279+
);
280+
verifyBundle_(
281+
i === 0 || bundle.name.localeCompare(bentoBundles[i - 1].name) >= 0,
282+
'name',
283+
'is out of order. bentoBundles should be alphabetically sorted by name.',
284+
bundle.name,
285+
bundleString
286+
);
287+
verifyBundle_(
288+
'version' in bundle,
289+
'version',
290+
'is missing from',
291+
bundle.name,
292+
bundleString
293+
);
294+
});
295+
};

Diff for: build-system/server/lazy-build.js

+42
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
'use strict';
22

33
const argv = require('minimist')(process.argv.slice(2));
4+
const {
5+
buildComponent,
6+
getBentoComponentsToBuild,
7+
maybeInitializeBentoComponents,
8+
} = require('../tasks/build-bento');
49
const {
510
doBuild3pVendor,
611
generateBundles,
@@ -17,6 +22,9 @@ const {VERSION} = require('../compile/internal-version');
1722
const extensionBundles = {};
1823
maybeInitializeExtensions(extensionBundles);
1924

25+
const bentoBundles = {};
26+
maybeInitializeBentoComponents(bentoBundles);
27+
2028
const vendorBundles = generateBundles();
2129

2230
/**
@@ -168,10 +176,44 @@ async function preBuildExtensions() {
168176
}
169177
}
170178

179+
/**
180+
* Normalized the callback from "build" and use it to build the inputted component.
181+
*
182+
* @param {!Object} components
183+
* @param {string} name
184+
* @param {?Object} options
185+
* @return {Promise<void|void[]>}
186+
*/
187+
function doBuildBentoComponent(components, name, options) {
188+
const component = components[name];
189+
return buildComponent(
190+
component.name,
191+
component.version,
192+
component.hasCss,
193+
{...options, ...component},
194+
component.extraGlobs
195+
);
196+
}
197+
198+
/**
199+
* Pre-builds default components and ones requested via command line flags.
200+
* @return {Promise<void>}
201+
*/
202+
async function preBuildBentoComponents() {
203+
const components = getBentoComponentsToBuild(/* preBuild */ true);
204+
for (const componentBundle in bentoBundles) {
205+
const component = bentoBundles[componentBundle].name;
206+
if (components.includes(component) && !componentBundle.endsWith('latest')) {
207+
await build(bentoBundles, componentBundle, doBuildBentoComponent);
208+
}
209+
}
210+
}
211+
171212
module.exports = {
172213
lazyBuildExtensions,
173214
lazyBuildJs,
174215
lazyBuild3pVendor,
175216
preBuildExtensions,
217+
preBuildBentoComponents,
176218
preBuildRuntimeFiles,
177219
};

Diff for: build-system/tasks/build-bento.js

+224
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
const argv = require('minimist')(process.argv.slice(2));
2+
const debounce = require('../common/debounce');
3+
const {
4+
buildBinaries,
5+
buildExtensionCss,
6+
buildExtensionJs,
7+
buildNpmBinaries,
8+
buildNpmCss,
9+
declareExtension,
10+
getBentoBuildFilename,
11+
getExtensionsFromArg,
12+
} = require('./extension-helpers');
13+
const {bentoBundles, verifyBentoBundles} = require('../compile/bundles.config');
14+
const {endBuildStep, watchDebounceDelay} = require('./helpers');
15+
const {getBentoName} = require('./bento-helpers');
16+
const {log} = require('../common/logging');
17+
const {mkdirSync} = require('fs');
18+
const {red} = require('kleur/colors');
19+
const {watch} = require('chokidar');
20+
21+
// All declared components.
22+
const COMPONENTS = {};
23+
24+
/**
25+
* Initializes all components from build-system/compile/bundles.config.bento.json
26+
* if not already done and populates the given components object.
27+
* @param {Object} componentsObject
28+
*/
29+
function maybeInitializeBentoComponents(componentsObject) {
30+
if (Object.keys(componentsObject).length > 0) {
31+
return;
32+
}
33+
verifyBentoBundles();
34+
bentoBundles.forEach((c) => {
35+
declareExtension(c.name, c.version, c.options, componentsObject);
36+
});
37+
}
38+
39+
/**
40+
* Process the command line arguments --nocomponents, --components, and
41+
* --components_from and return a list of the referenced components.
42+
*
43+
* @param {boolean} preBuild Used for lazy building of components.
44+
* @return {!Array<string>}
45+
*/
46+
function getBentoComponentsToBuild(preBuild = false) {
47+
const componentsToBuild = new Set();
48+
if (argv.extensions) {
49+
if (typeof argv.extensions !== 'string') {
50+
log(red('ERROR:'), 'Missing list of components.');
51+
process.exit(1);
52+
}
53+
const explicitComponents = argv.extensions.replace(/\s/g, '').split(',');
54+
explicitComponents.forEach((component) => componentsToBuild.add(component));
55+
}
56+
if (argv.extensions_from) {
57+
const componentsFrom = getExtensionsFromArg(argv.extensions_from);
58+
componentsFrom.forEach((component) => componentsToBuild.add(component));
59+
}
60+
if (
61+
!preBuild &&
62+
!argv.nocomponents &&
63+
!argv.extensions &&
64+
!argv.extensions_from &&
65+
!argv.core_runtime_only
66+
) {
67+
const allComponents = Object.values(COMPONENTS).map((c) => c.name);
68+
allComponents.forEach((component) => componentsToBuild.add(component));
69+
}
70+
return Array.from(componentsToBuild);
71+
}
72+
73+
/**
74+
* Watches for non-JS changes within an components directory to trigger
75+
* recompilation.
76+
*
77+
* @param {string} componentsDir
78+
* @param {string} name
79+
* @param {string} version
80+
* @param {boolean} hasCss
81+
* @param {?Object} options
82+
* @return {Promise<void>}
83+
*/
84+
async function watchBentoComponent(
85+
componentsDir,
86+
name,
87+
version,
88+
hasCss,
89+
options
90+
) {
91+
/**
92+
* Steps to run when a watched file is modified.
93+
*/
94+
function watchFunc() {
95+
buildBentoComponent(name, version, hasCss, {
96+
...options,
97+
continueOnError: true,
98+
isRebuild: true,
99+
watch: false,
100+
});
101+
}
102+
103+
const cssDeps = `${componentsDir}/**/*.css`;
104+
const ignored = /dist/; //should not watch npm dist folders.
105+
watch([cssDeps], {ignored}).on(
106+
'change',
107+
debounce(watchFunc, watchDebounceDelay)
108+
);
109+
}
110+
111+
/**
112+
* Copies components from
113+
* src/bento/components/$name/$name.js
114+
* to
115+
* dist/v0/$name-$version.js
116+
*
117+
* Optionally copies the CSS at components/$name/$version/$name.css into
118+
* a generated JS file that can be required from the components as
119+
* `import {CSS} from '../../../build/$name-0.1.css';`
120+
*
121+
* @param {string} name Name of the extension. Must be the sub directory in
122+
* the components directory and the name of the JS and optional CSS file.
123+
* @param {string} version Version of the extension. Must be identical to
124+
* the sub directory inside the extension directory
125+
* @param {boolean} hasCss Whether there is a CSS file for this extension.
126+
* @param {?Object} options
127+
* @param {!Array=} extraGlobs
128+
* @return {!Promise<void|void[]>}
129+
*/
130+
async function buildBentoComponent(
131+
name,
132+
version,
133+
hasCss,
134+
options = {},
135+
extraGlobs
136+
) {
137+
options.extraGlobs = extraGlobs;
138+
options.npm = true;
139+
options.bento = true;
140+
141+
if (options.compileOnlyCss && !hasCss) {
142+
return;
143+
}
144+
const componentsDir = `src/bento/components/${name}/${version}`;
145+
if (options.watch) {
146+
await watchBentoComponent(componentsDir, name, version, hasCss, options);
147+
}
148+
149+
/** @type {Promise<void>[]} */
150+
const promises = [];
151+
if (hasCss) {
152+
mkdirSync('build/css', {recursive: true});
153+
promises.push(buildExtensionCss(componentsDir, name, version, options));
154+
if (options.compileOnlyCss) {
155+
return Promise.all(promises);
156+
}
157+
}
158+
promises.push(buildNpmBinaries(componentsDir, name, options));
159+
promises.push(buildNpmCss(componentsDir, options));
160+
if (options.binaries) {
161+
promises.push(buildBinaries(componentsDir, options.binaries, options));
162+
}
163+
if (options.isRebuild) {
164+
return Promise.all(promises);
165+
}
166+
167+
const bentoName = getBentoName(name);
168+
promises.push(
169+
buildExtensionJs(componentsDir, bentoName, {
170+
...options,
171+
wrapper: 'none',
172+
filename: await getBentoBuildFilename(
173+
componentsDir,
174+
bentoName,
175+
'standalone',
176+
options
177+
),
178+
// Include extension directory since our entrypoint may be elsewhere.
179+
extraGlobs: [...(options.extraGlobs || []), `${componentsDir}/**/*.js`],
180+
})
181+
);
182+
return Promise.all(promises);
183+
}
184+
185+
/**
186+
* Build all the Bento components
187+
*
188+
* @param {!Object} options
189+
* @return {!Promise<void>}
190+
*/
191+
async function buildBentoComponents(options) {
192+
const startTime = Date.now();
193+
maybeInitializeBentoComponents(COMPONENTS);
194+
const toBuild = getBentoComponentsToBuild();
195+
const results = Object.values(COMPONENTS)
196+
.filter(
197+
(component) => options.compileOnlyCss || toBuild.includes(component.name)
198+
)
199+
.map((component) =>
200+
buildBentoComponent(
201+
component.name,
202+
component.version,
203+
component.hasCss,
204+
{...options, ...component},
205+
component.extraGlobs
206+
)
207+
);
208+
209+
await Promise.all(results);
210+
if (!options.compileOnlyCss && results.length > 0) {
211+
endBuildStep(
212+
options.minify ? 'Minified all' : 'Compiled all',
213+
'components',
214+
startTime
215+
);
216+
}
217+
}
218+
219+
module.exports = {
220+
buildBentoComponents,
221+
buildComponent: buildBentoComponent,
222+
getBentoComponentsToBuild,
223+
maybeInitializeBentoComponents,
224+
};

0 commit comments

Comments
 (0)