Skip to content

Commit

Permalink
Convert bundling to use Rollup
Browse files Browse the repository at this point in the history
Change bundling in development and when running tests to use Browserify
rather than Rollup. This adapts the changes that were recently made in
the lms [1] and client [2] projects.

[1] hypothesis/lms#3221
[2] hypothesis/client#3840
  • Loading branch information
robertknight committed Oct 18, 2021
1 parent b510b22 commit 9194676
Show file tree
Hide file tree
Showing 13 changed files with 458 additions and 1,556 deletions.
4 changes: 1 addition & 3 deletions .babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ module.exports = {
{
development: true,
runtime: 'automatic',
// Use `preact/compat/jsx-dev-runtime` which is an alias for `preact/jsx-runtime`.
// See https://github.com/preactjs/preact/issues/2974.
importSource: 'preact/compat',
importSource: 'preact',
},
],
],
Expand Down
9 changes: 8 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@
"react/react-in-jsx-scope": "off",
// Replaced by TypeScript's static checking.
"react/prop-types": "off"
}
},
"overrides": [
{
"files": ["rollup*.mjs", "scripts/pattern-library.js"],
"env": { "node": true },
"parserOptions": { "sourceType": "module" }
}
]
}
184 changes: 128 additions & 56 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
/* eslint-env node */
('use strict');
'use strict';

const fs = require('fs');
const path = require('path');

const commander = require('commander');
const log = require('fancy-log');
const glob = require('glob');
const gulp = require('gulp');
const rollup = require('rollup');
const sass = require('sass');

const createBundle = require('./scripts/gulp/create-bundle');
const createStyleBundle = require('./scripts/gulp/create-style-bundle');
const servePatternLibrary = require('./scripts/serve-pattern-library');

const IS_PRODUCTION_BUILD = process.env.NODE_ENV === 'production';

const SCRIPT_DIR = 'build/scripts';
const STYLE_DIR = 'build/styles';

const appBundles = [
{
// A web app to assist with testing UI components.
name: 'pattern-library',
entry: './scripts/pattern-library',
path: SCRIPT_DIR,
transforms: ['babel'],
},
];

const cssBundles = ['./styles/pattern-library.scss'];

function parseCommandLine() {
Expand Down Expand Up @@ -60,17 +50,57 @@ function parseCommandLine() {
}

const karmaOptions = parseCommandLine();
const { run } = require('./scripts/gulp/run');

function runKarma(done) {
const karma = require('karma');
new karma.Server(
{
configFile: `${__dirname}/src/karma.config.js`,
...karmaOptions,
},
done
).start();

/** @param {import('rollup').RollupWarning} */
function logRollupWarning(warning) {
log.info(`Rollup warning: ${warning} (${warning.url})`);
}

async function buildJS(rollupConfig) {
let { default: configs } = await import(rollupConfig);
if (!Array.isArray(configs)) {
configs = [configs];
}

await Promise.all(
configs.map(async config => {
const bundle = await rollup.rollup({
...config,
onwarn: logRollupWarning,
});
await bundle.write(config.output);
})
);
}

async function watchJS(rollupConfig) {
const { default: configs } = await import(rollupConfig);
const watcher = rollup.watch(
configs.map(config => ({
...config,
onwarn: logRollupWarning,
}))
);

return new Promise(resolve => {
watcher.on('event', event => {
switch (event.code) {
case 'START':
log.info('JS build starting...');
break;
case 'BUNDLE_END':
event.result.close();
break;
case 'ERROR':
log.info('JS build error', event.error);
break;
case 'END':
log.info('JS build completed.');
resolve(); // Resolve once the initial build completes.
break;
}
});
});
}

/**
Expand All @@ -95,41 +125,13 @@ gulp.task('changelog', async () => {
console.log(changelog.toString());
});

/**
* Task to build a CSS bundle.
*
* nb. This is only used for unit tests that need CSS to verify accessibility requirements.
*/
gulp.task('build-test-css', done => {
fs.mkdirSync('build', { recursive: true });
const result = sass.renderSync({
file: 'styles/index.scss',
outFile: 'build/styles.css',
sourceMap: true,
});

fs.writeFileSync('build/styles.css', result.css);
fs.writeFileSync('build/styles.css.map', result.map);
done();
});

gulp.task(
'test',
gulp.series('build-test-css', done => runKarma(done))
);

gulp.task('serve-pattern-library', () => {
servePatternLibrary();
});

// The following tasks bundle assets for the pattern library for use locally
// during development. Bundled JS and CSS are not published with the package.

// Bundle JS into local `build` folder
gulp.task('bundle-js', () => {
return Promise.all(appBundles.map(config => createBundle(config)));
});

// Bundle SASS into local `build` folder
gulp.task('bundle-css', function () {
fs.mkdirSync(STYLE_DIR, { recursive: true });
Expand All @@ -150,11 +152,81 @@ gulp.task(
)
);

gulp.task('watch-js', () =>
Promise.all(appBundles.map(config => createBundle(config, { watch: true })))
);
gulp.task('watch-js', () => watchJS('./rollup.config.mjs'));

gulp.task(
'watch',
gulp.parallel('serve-pattern-library', 'watch-css', 'watch-js')
);

/**
* Task to build a CSS bundle.
*
* nb. This is only used for unit tests that need CSS to verify accessibility requirements.
*/
gulp.task('build-test-css', done => {
fs.mkdirSync('build', { recursive: true });
const result = sass.renderSync({
file: 'styles/index.scss',
outFile: 'build/styles.css',
sourceMap: true,
});

fs.writeFileSync('build/styles.css', result.css);
fs.writeFileSync('build/styles.css.map', result.map);
done();
});

async function buildAndRunTests() {
const { grep, singleRun } = karmaOptions;

// Generate an entry file for the test bundle. This imports all the test
// modules, filtered by the pattern specified by the `--grep` CLI option.
const testFiles = [
'test/bootstrap.js',
...glob
.sync('src/**/*-test.js')
.filter(path => (grep ? path.match(grep) : true)),
];

const testSource = testFiles
.map(path => `import "../../${path}";`)
.join('\n');

fs.mkdirSync('build/scripts', { recursive: true });
fs.writeFileSync('build/scripts/test-inputs.js', testSource);

// Build the test bundle.
log.info(`Building test bundle... (${testFiles.length} files)`);
if (singleRun) {
await buildJS('./rollup-tests.config.mjs');
} else {
await watchJS('./rollup-tests.config.mjs');
}

// Run the tests.
log.info('Starting Karma...');
return new Promise(resolve => {
const karma = require('karma');
new karma.Server(
karma.config.parseConfig(
path.resolve(__dirname, './src/karma.config.js'),
{ singleRun }
),
resolve
).start();

process.on('SIGINT', () => {
// Give Karma a chance to handle SIGINT and cleanup, but forcibly
// exit if it takes too long.
setTimeout(() => {
resolve();
process.exit(1);
}, 5000);
});
});
}

// Some (eg. a11y) tests rely on CSS bundles. We assume that JS will always take
// longer to build than CSS, so build in parallel.
gulp.task('test', gulp.parallel('build-test-css', buildAndRunTests));
31 changes: 8 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
"@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^21.0.0",
"@rollup/plugin-node-resolve": "^13.0.5",
"@rollup/plugin-virtual": "^2.0.3",
"auto-changelog": "^2.2.1",
"autoprefixer": "^10.2.5",
"axe-core": "^4.0.0",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-mockable-imports": "^1.7.1",
"babelify": "^10.0.0",
"browserify": "^17.0.0",
"chai": "^4.1.2",
"classnames": "^2.2.6",
"commander": "^7.1.0",
Expand All @@ -27,18 +29,17 @@
"eslint-plugin-mocha": "^8.0.0",
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-react-hooks": "^4.0.4",
"exorcist": "^2.0.0",
"express": "^4.17.1",
"fancy-log": "^1.3.3",
"gulp": "^4.0.0",
"karma": "^6.0.1",
"karma-browserify": "^8.0.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-reporter": "^3.0.3",
"karma-mocha": "^2.0.0",
"karma-mocha-reporter": "^2.0.4",
"karma-sinon": "^1.0.5",
"karma-source-map-support": "^1.4.0",
"mocha": "8.2.1",
"mustache": "^4.2.0",
"mustache-express": "^1.3.0",
Expand All @@ -47,12 +48,11 @@
"preact": "^10.4.0",
"prettier": "^2.2.1",
"puppeteer": "^7.1.0",
"rollup": "^2.58.0",
"rollup-plugin-string": "^3.0.0",
"sass": "^1.32.11",
"sinon": "^9.0.0",
"stringify": "^5.1.0",
"terser": "^5.7.0",
"typescript": "^4.1.5",
"watchify": "^4.0.0",
"yalc": "^1.0.0-pre.50"
},
"peerDependencies": {
Expand Down Expand Up @@ -82,20 +82,5 @@
],
"main": "./lib-cjs/index.js",
"module": "./lib/index.js",
"browserslist": "chrome 70, firefox 70, safari 11.1",
"browserify": {
"transform": [
[
"stringify",
{
"appliesTo": {
"includeExtensions": [
".html",
".svg"
]
}
}
]
]
}
"browserslist": "chrome 70, firefox 70, safari 11.1"
}
Loading

0 comments on commit 9194676

Please sign in to comment.