Skip to content

Commit

Permalink
fix: Use relative paths in exports field (#168)
Browse files Browse the repository at this point in the history
* test(ci): Run with active node versions

* fix: avoid duplicate artifacts by specifying node version

* test: Smoke test for unflagged es modules in node

* Remove core-js dependency

there's no set/array-from polyfill written with ES6 modules

* fix: resolve node_version to value

* like so?

* fix working directory

* fix: use correct relative imports in .mjs files

* Enable fallback

* Create serious-tables-deny.md
  • Loading branch information
eps1lon committed Mar 24, 2020
1 parent 7081f92 commit b421d9e
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 19 deletions.
34 changes: 34 additions & 0 deletions .babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
],
require.resolve("@babel/preset-typescript"),
],
plugins: [require.resolve("@babel/plugin-proposal-class-properties")],
env: {
cjs: {
plugins: [
Expand All @@ -19,5 +20,38 @@ module.exports = {
],
],
},
esm: {
plugins: [
function rewriteRelativeImportsToMjs() {
const extension = "mjs";
/**
*
* @param {ImportDeclaration | ExportNamedDeclaration} declaration
*/
function rewriteRelativeImports(declaration) {
if (declaration.source === null) {
return;
}

const specifier = declaration.source.value;
const isRelativeSpecifier = specifier.startsWith(".");
if (isRelativeSpecifier) {
declaration.source.value = `${specifier}.${extension}`;
}
}

return {
visitor: {
ExportNamedDeclaration(path, state) {
rewriteRelativeImports(path.node);
},
ImportDeclaration(path, state) {
rewriteRelativeImports(path.node);
},
},
};
},
],
},
},
};
7 changes: 7 additions & 0 deletions .changeset/serious-tables-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"dom-accessibility-api": patch
---

fix: Use relative paths in exports field

Fixes a crash when using ES modules in Node.
33 changes: 24 additions & 9 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@ pr:
pool:
vmImage: "ubuntu-latest"

# TODO we don't actually need this for karma or cypress tests
# but it let's us use a single job. No need to split up jobs yet
strategy:
matrix:
# active node versions
node_10_x:
node_version: 10.x
node_12_x:
node_version: 12.x
node_13_x:
node_version: 13.x

steps:
- task: NodeTool@0
inputs:
versionSpec: "12.11.x"
versionSpec: $(node_version)
displayName: "Install Node.js"

- script: |
Expand Down Expand Up @@ -44,6 +56,13 @@ steps:
displayName: "kcd-rollup smoke tests of build"
workingDirectory: tests/build/fixtures/kcd-rollup

- script: yarn start
displayName: "ES modules in node smoke tests of build"
workingDirectory: tests/build/fixtures/node-es-modules
# in node 12 we need to use a flag and I'm to lazy to branch even further
# running in node 13 is hopefully a sufficient smoke test
condition: startsWith(variables['node_version'], '13.')

- script: yarn test:ci
displayName: "Run jest tests"

Expand All @@ -70,15 +89,11 @@ steps:
- script: yarn test:wpt:browser
displayName: "Run wpt tests in browser"

- task: PublishPipelineArtifact@0
inputs:
artifactName: "browser-test-screenshots"
targetPath: "tests/cypress/screenshots"
- publish: tests/cypress/screenshots
artifact: browser-test-screenshots-node-$(node_version)
condition: failed()
displayName: "Publish cypress screenshots"

- task: PublishPipelineArtifact@0
inputs:
artifactName: "browser-test-videos"
targetPath: "tests/cypress/videos"
- publish: tests/cypress/videos
artifact: browser-test-videos-node-$(node_version)
displayName: "Publish cypress screenshots"
11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@
"main": "dist/index.js",
"type": "commonjs",
"exports": {
"import": "dist/index.mjs",
"require": "dist/index.js"
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/eps1lon/dom-accessibility-api.git"
},
"dependencies": {
"core-js-pure": "^3.6.4"
},
"dependencies": {},
"files": [
".browserslistrc",
"dist/"
],
"scripts": {
"build": "yarn build:clean && yarn build:source && yarn build:source:cjs && yarn build:types",
"build:clean": "rimraf dist",
"build:source": "babel sources --extensions \".ts\" --ignore \"**/__tests__/**/*\" --out-dir dist/ --out-file-extension=.mjs --source-maps",
"build:source": "cross-env BABEL_ENV=esm babel sources --extensions \".ts\" --ignore \"**/__tests__/**/*\" --out-dir dist/ --out-file-extension=.mjs --source-maps",
"build:source:cjs": "cross-env BABEL_ENV=cjs babel sources --extensions \".ts\" --ignore \"**/__tests__/**/*\" --out-dir dist/ --out-file-extension=.js --source-maps",
"build:types": "tsc -p tsconfig.json --emitDeclarationOnly",
"format": "prettier \"**/*.{json,js,md,ts,yml}\" --write --ignore-path .prettierignore",
Expand All @@ -45,6 +43,7 @@
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-transform-modules-commonjs": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"@babel/preset-typescript": "^7.9.0",
Expand Down
6 changes: 3 additions & 3 deletions sources/accessible-name.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
* implements https://w3c.github.io/accname/
*/
import ArrayFrom from "core-js-pure/features/array/from";
import Set from "core-js-pure/stable/set";
import ArrayFrom from "./polyfills/array.from";
import SetLike from "./polyfills/SetLike";
import getRole from "./getRole";
import {
isElement,
Expand Down Expand Up @@ -292,7 +292,7 @@ export function computeAccessibleName(
root: Element,
options: GetComputedStyleOptions = {}
): string {
const consultedNodes = new Set<Node>();
const consultedNodes = new SetLike<Node>();

if (prohibitsNaming(root)) {
return "" as FlatString;
Expand Down
52 changes: 52 additions & 0 deletions sources/polyfills/SetLike.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
declare global {
class Set<T> {
// es2015.collection.d.ts
add(value: T): this;
clear(): void;
delete(value: T): boolean;
forEach(
callbackfn: (value: T, value2: T, set: Set<T>) => void,
thisArg?: any
): void;
has(value: T): boolean;
readonly size: number;

// es2015.iterable.d.ts
// no implemennted
}
}

// for environments without Set we fallback to arrays with unique members
class SetLike<T> extends Set<T> {
private items: T[] = [];

add(value: T): this {
if (this.has(value) === false) {
this.items.push(value);
}
return this;
}
clear(): void {
this.items = [];
}
delete(value: T): boolean {
const previousLength = this.items.length;
this.items = this.items.filter((item) => item !== value);

return previousLength !== this.items.length;
}
forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void): void {
this.items.forEach((item) => {
callbackfn(item, item, this);
});
}
has(value: T): boolean {
return this.items.indexOf(value) !== -1;
}

get size(): number {
return this.items.length;
}
}

export default typeof Set === "undefined" ? Set : SetLike;
93 changes: 93 additions & 0 deletions sources/polyfills/array.from.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* @source {https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Polyfill}
* but without thisArg (too hard to type, no need to `this`)
*/
const toStr = Object.prototype.toString;
function isCallable(fn: unknown): boolean {
return typeof fn === "function" || toStr.call(fn) === "[object Function]";
}
function toInteger(value: unknown): number {
const number = Number(value);
if (isNaN(number)) {
return 0;
}
if (number === 0 || !isFinite(number)) {
return number;
}
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
}
const maxSafeInteger = Math.pow(2, 53) - 1;
function toLength(value: unknown): number {
const len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
}
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
*/
export default function arrayFrom<T>(iterable: Iterable<T> | ArrayLike<T>): T[];
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
export default function arrayFrom<T, U>(
arrayLike: Iterable<T> | ArrayLike<T>,
mapFn?: (v: T, k: number) => U
): U[] {
// 1. Let C be the this value.
// edit(@eps1lon): we're not calling it as Array.from
const C = Array;

// 2. Let items be ToObject(arrayLike).
const items = Object(arrayLike);

// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError(
"Array.from requires an array-like object - not null or undefined"
);
}

// 4. If mapfn is undefined, then let mapping be false.
// const mapFn = arguments.length > 1 ? arguments[1] : void undefined;

if (typeof mapFn !== "undefined") {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError(
"Array.from: when provided, the second argument must be a function"
);
}
}

// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
const len = toLength(items.length);

// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method
// of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
const A = isCallable(C) ? Object(new C(len)) : new Array(len);

// 16. Let k be 0.
let k = 0;
// 17. Repeat, while k < len… (also steps a - h)
let kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = mapFn(kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
}
3 changes: 3 additions & 0 deletions tests/build/fixtures/node-es-modules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# node-es-modules

Smoke test for interaction between node and publishing dual-modules.
4 changes: 4 additions & 0 deletions tests/build/fixtures/node-es-modules/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as assert from "assert";
import { computeAccessibleName } from "dom-accessibility-api";

assert.strictEqual(typeof computeAccessibleName, "function");
11 changes: 11 additions & 0 deletions tests/build/fixtures/node-es-modules/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "build-fixture-node-es-modules",
"private": true,
"type": "module",
"dependencies": {
"dom-accessibility-api": "file:../../../../dom-accessibility-api.tgz"
},
"scripts": {
"start": "yarn install --no-lockfile && node index.js"
}
}
10 changes: 9 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@
"@babel/helper-remap-async-to-generator" "^7.8.3"
"@babel/plugin-syntax-async-generators" "^7.8.0"

"@babel/plugin-proposal-class-properties@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e"
integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.8.3"
"@babel/helper-plugin-utils" "^7.8.3"

"@babel/plugin-proposal-dynamic-import@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz#38c4fe555744826e97e2ae930b0fb4cc07e66054"
Expand Down Expand Up @@ -2380,7 +2388,7 @@ core-js-compat@^3.6.2:
browserslist "^4.8.3"
semver "7.0.0"

core-js-pure@^3.0.0, core-js-pure@^3.6.4:
core-js-pure@^3.0.0:
version "3.6.4"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a"
integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==
Expand Down

0 comments on commit b421d9e

Please sign in to comment.