Skip to content

Commit

Permalink
Build: Add native ESM distribution
Browse files Browse the repository at this point in the history
  • Loading branch information
Krinkle committed Aug 27, 2024
1 parent 6799e6a commit ab12f20
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 119 deletions.
6 changes: 6 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ module.exports = function (grunt) {
'src-css': {
src: 'src/core/qunit.css',
dest: 'qunit/qunit.css'
},
'src-export-wrappers': {
src: 'src/core/export-*.js',
expand: true,
flatten: true,
dest: 'qunit/'
}
},
search: {
Expand Down
2 changes: 1 addition & 1 deletion demos/bundlers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const dirname = path.dirname(url.fileURLToPath(import.meta.url));
const DIR = path.join(dirname, 'bundlers');

// Prepare
cp.execSync('npm install --no-audit --update-notifier=false', { cwd: DIR, encoding: 'utf8' });
// cp.execSync('npm install --no-audit --update-notifier=false', { cwd: DIR, encoding: 'utf8' });
await import('./bundlers/build.mjs');

const tmpJsFiles = fs.readdirSync(path.join(DIR, 'tmp'))
Expand Down
18 changes: 16 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@
"LICENSE.txt"
],
"main": "qunit/qunit.js",
"exports": {
".": {
"node": {
"import": "./qunit/export-wrapper-nodejs-module.js",
"default": "./qunit/qunit.js"
},
"module": {
"import": "./qunit/qunit.module.js",
"default": "./qunit/export-wrapper-bundler-require.js"
},
"import": "./qunit/qunit.module.js",
"default": "./qunit/qunit.js"
}
},
"engines": {
"node": ">=18"
},
Expand Down Expand Up @@ -82,8 +96,8 @@
"tap-min": "^3.0.0"
},
"scripts": {
"build": "rollup -c && grunt copy:src-css",
"build-coverage": "rollup -c --environment BUILD_TARGET:coverage && grunt copy:src-css",
"build": "rollup -c && grunt copy",
"build-coverage": "rollup -c --environment BUILD_TARGET:coverage && grunt copy",
"build-dev": "node build/dev.js",
"benchmark": "npm install --silent --no-audit --prefix test/benchmark/ && node test/benchmark/micro.js",
"lint": "eslint --cache .",
Expand Down
108 changes: 69 additions & 39 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,74 @@ const replace = require('@rollup/plugin-replace');
const { replacements } = require('./build/dist-replace.js');
const isCoverage = process.env.BUILD_TARGET === 'coverage';

module.exports = {
input: 'src/core/qunit.js',
output: {
file: 'qunit/qunit.js',
sourcemap: isCoverage,
format: 'iife',
exports: 'none',
const banner = `/*!
* QUnit @VERSION
* https://qunitjs.com/
*
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*/`;

// eslint-disable-next-line no-multi-str
banner: '/*!\n\
* QUnit @VERSION\n\
* https://qunitjs.com/\n\
*\n\
* Copyright OpenJS Foundation and other contributors\n\
* Released under the MIT license\n\
* https://jquery.org/license\n\
*/'
},
plugins: [
replace({
preventAssignment: true,
delimiters: ['', ''],
...replacements
}),
nodeResolve(),
commonjs(),
babel({
babelHelpers: 'bundled',
babelrc: false,
presets: [
['@babel/preset-env', {
targets: {
ie: 11,
safari: 7,
node: 18
}
}]
]
})
]
const replacementOptions = {
preventAssignment: true,
delimiters: ['', ''],
...replacements
};

module.exports = [
{
input: 'src/core/qunit-commonjs.js',
output: {
file: 'qunit/qunit.js',
sourcemap: isCoverage,
format: 'iife',
exports: 'none',
banner: banner
},
plugins: [
replace(replacementOptions),
nodeResolve(),
commonjs(),
babel({
babelHelpers: 'bundled',
babelrc: false,
presets: [
['@babel/preset-env', {
targets: {
ie: 11,
safari: 7,
node: 18
}
}]
]
})
]
},
{
input: 'src/core/qunit.js',
output: {
file: 'qunit/qunit.module.js',
format: 'es',
exports: 'named',
banner: banner
},
plugins: [
replace(replacementOptions),
nodeResolve(),
commonjs(),
babel({
babelHelpers: 'bundled',
babelrc: false,
presets: [
['@babel/preset-env', {
targets: {
safari: 10,
node: 18
}
}]
]
})
]
}
];
7 changes: 7 additions & 0 deletions src/core/export-wrapper-bundler-require.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// In a single bundler invocation, if different parts or dependencies
// of a project mix ESM and CJS, avoid a split-brain state by making
// sure both import and re-use the same instance via this wrapper.
//
// Bundlers generally allow requiring an ESM file from CommonJS.
const { QUnit } = require('./qunit.module.js');
module.exports = QUnit;
45 changes: 45 additions & 0 deletions src/core/export-wrapper-nodejs-module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// In a single Node.js process, if different parts or dependencies
// of a project mix ESM and CJS, avoid a split-brain state by making
// sure both import and re-use the same instance via this wrapper.
//
// The "real" ESM file is reserved for bundlers, web distribution,
// and other consumers of package.json#exports.module.
//
// Node.js 18+ can import a CommonJS file from ESM.
import QUnit from "./qunit.js";

export const {
assert,
begin,
config,
diff,
done,
dump,
equiv,
hooks,
is,
isLocal,
log,
module,
moduleDone,
moduleStart,
objectType,
on,
only,
onUncaughtException,
pushFailure,
reporters,
skip,
stack,
start,
test,
testDone,
testStart,
todo,
urlParams,
version
} = QUnit;

export { QUnit };

export default QUnit;
51 changes: 0 additions & 51 deletions src/core/export.js

This file was deleted.

12 changes: 12 additions & 0 deletions src/core/qunit-commonjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* global module, exports */
import QUnit from './qunit.js';

// For Node.js
if (typeof module !== 'undefined' && module && module.exports) {
module.exports = QUnit;
}

// For CommonJS with exports, but without module.exports, like Rhino
if (typeof exports !== 'undefined' && exports) {
exports.QUnit = QUnit;
}
Loading

0 comments on commit ab12f20

Please sign in to comment.