Skip to content

Commit

Permalink
Adding dev-libs attribute for automatic overrides to dev versions (#8)
Browse files Browse the repository at this point in the history
* Adding dev-libs attribute for automatic overrides to dev versions

* Documentation

* Self review

* Self review
  • Loading branch information
joeldenning authored Dec 2, 2019
1 parent f19b0db commit 724d9fd
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 49 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# import-map-overrides

[![](https://data.jsdelivr.com/v1/package/npm/import-map-overrides/badge)](https://www.jsdelivr.com/package/npm/import-map-overrides)

A browser javascript library for being able to override [import maps](https://github.com/WICG/import-maps). This works
Expand Down Expand Up @@ -190,9 +191,15 @@ You have three options for the UI, depending on how much you want to customize t
For example, in the below example you must run the follow command in order to see the full-ui.
localStorage.setItem('overrides-ui', true);
The dev-libs attribute indicates that you prefer using development versions of third party libraries
like react when the import-map-overrides ui is active. The presence of that attribute turns on this feature.
For example, if you have `react` in your import map pointing to https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js
the dev-libs attribute will automatically override it to https://cdn.jsdelivr.net/npm/react/umd/react.development.js.
-->
<import-map-overrides-full
show-when-local-storage="overrides-ui"
dev-libs
></import-map-overrides-full>

<!-- Alternatively, just the black popup itself -->
Expand Down
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
"author": "Joel Denning <[email protected]>",
"license": "MIT",
"scripts": {
"build": "rimraf dist && rollup -c",
"watch": "rollup -c --watch",
"test": "npm run build && copyfiles test/index.html dist -f && serve .",
"build": "yarn clean && cross-env NODE_ENV=production rollup -c",
"build:dev": "yarn clean && cross-env NODE_ENV=development rollup -c",
"clean": "rimraf dist",
"watch": "cross-env NODE_ENV=development rollup -c --watch",
"test": "concurrently yarn:watch 'copyfiles test/index.html dist -f' 'serve .'",
"prepublishOnly": "yarn build"
},
"husky": {
Expand All @@ -27,7 +29,9 @@
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-transform-react-jsx": "^7.3.0",
"@babel/preset-env": "^7.6.3",
"concurrently": "^5.0.0",
"copyfiles": "^2.1.1",
"cross-env": "^6.0.3",
"husky": "^3.0.9",
"preact": "^10.0.4",
"prettier": "^1.18.2",
Expand Down
29 changes: 16 additions & 13 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { terser } from "rollup-plugin-terser";
import resolve from "rollup-plugin-node-resolve";
import postcss from "rollup-plugin-postcss";

const isProduction = process.env.NODE_ENV === "production";

export default [
// Full library with UI
{
Expand All @@ -18,12 +20,13 @@ export default [
}),
resolve(),
postcss(),
terser({
compress: {
passes: 2
},
sourcemap: true
})
isProduction &&
terser({
compress: {
passes: 2
},
sourcemap: true
})
]
},
// Only the global variable API. No UI
Expand All @@ -38,13 +41,13 @@ export default [
babel({
exclude: "node_modules/**"
}),
terser({
compress: {
unsafe: true,
passes: 2
},
sourcemap: true
})
isProduction &&
terser({
compress: {
passes: 2
},
sourcemap: true
})
]
}
];
35 changes: 35 additions & 0 deletions src/ui/dev-lib-overrides.component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { h, Component } from "preact";
import { getDefaultMap } from "./list/list.component";

export default class DevLibOverrides extends Component {
componentDidMount() {
getDefaultMap().then(addDevLibOverrides);
}
render() {
return null;
}
}

const devLibs = {
react: url => url.replace("production.min", "development"),
"react-dom": url => url.replace("production.min", "development")
};

function addDevLibOverrides(notOverriddenMap) {
Object.keys(notOverriddenMap.imports)
.filter(libName => devLibs[libName])
.forEach(libName => {
window.importMapOverrides.addOverride(
libName,
devLibs[libName](notOverriddenMap.imports[libName])
);
});
}

export function overridesBesidesDevLibs() {
return (
Object.keys(window.importMapOverrides.getOverrideMap().imports).filter(
k => !devLibs[k]
).length > 0
);
}
22 changes: 17 additions & 5 deletions src/ui/full-ui.component.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { h, Component } from "preact";
import Popup from "./popup.component";
import DevLibOverrides, {
overridesBesidesDevLibs
} from "./dev-lib-overrides.component";

export default class FullUI extends Component {
state = {
Expand All @@ -23,20 +26,19 @@ export default class FullUI extends Component {
return null;
}

const atLeastOneOverride =
Object.keys(window.importMapOverrides.getOverrideMap().imports).length >
0;

return (
<div>
<button
onClick={this.toggleTrigger}
className={`imo-unstyled imo-trigger ${
atLeastOneOverride ? "imo-overridden" : ""
this.atLeastOneOverride() ? "imo-overridden" : ""
}`}
>
{"{\u00B7\u00B7\u00B7}"}
</button>
{this.props.customElement.hasAttribute("dev-libs") && (
<DevLibOverrides />
)}
{state.showingPopup && (
<Popup
close={this.toggleTrigger}
Expand All @@ -54,4 +56,14 @@ export default class FullUI extends Component {
importMapChanged = () => {
this.forceUpdate();
};
atLeastOneOverride = () => {
if (this.props.customElement.hasAttribute("dev-libs")) {
return overridesBesidesDevLibs();
} else {
return (
Object.keys(window.importMapOverrides.getOverrideMap().imports).length >
0
);
}
};
}
46 changes: 24 additions & 22 deletions src/ui/list/list.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,7 @@ export default class List extends Component {
searchVal: ""
};
componentDidMount() {
const notOverriddenMapPromise = Array.prototype.reduce.call(
document.querySelectorAll(`script[type="${importMapType}"]`),
(promise, scriptEl) => {
if (scriptEl.id === "import-map-overrides") {
return promise;
} else {
let nextPromise;
if (scriptEl.src) {
nextPromise = fetch(scriptEl.src).then(resp => resp.json());
} else {
nextPromise = Promise.resolve(JSON.parse(scriptEl.textContent));
}

return Promise.all([promise, nextPromise]).then(
([originalMap, newMap]) => mergeImportMap(originalMap, newMap)
);
}
},
Promise.resolve(this.state.notOverriddenMap)
);

notOverriddenMapPromise.then(notOverriddenMap => {
getDefaultMap().then(notOverriddenMap => {
this.setState({ notOverriddenMap });
});
window.addEventListener("import-map-overrides:change", this.doUpdate);
Expand Down Expand Up @@ -191,6 +170,29 @@ export default class List extends Component {
};
}

export function getDefaultMap() {
return Array.prototype.reduce.call(
document.querySelectorAll(`script[type="${importMapType}"]`),
(promise, scriptEl) => {
if (scriptEl.id === "import-map-overrides") {
return promise;
} else {
let nextPromise;
if (scriptEl.src) {
nextPromise = fetch(scriptEl.src).then(resp => resp.json());
} else {
nextPromise = Promise.resolve(JSON.parse(scriptEl.textContent));
}

return Promise.all([promise, nextPromise]).then(
([originalMap, newMap]) => mergeImportMap(originalMap, newMap)
);
}
},
Promise.resolve({ imports: {} })
);
}

function mergeImportMap(originalMap, newMap) {
for (let i in newMap.imports) {
originalMap.imports[i] = newMap.imports[i];
Expand Down
6 changes: 4 additions & 2 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
<script type="importmap">
{
"imports": {
"a": "./a.js"
"a": "./a.js",
"react": "https://cdn.jsdelivr.net/npm/[email protected]/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/[email protected]/umd/react-dom.production.min.js"
}
}
</script>
<script src="/import-map-overrides.js"></script>
</head>
<body>
<import-map-overrides-full></import-map-overrides-full>
<import-map-overrides-full dev-libs></import-map-overrides-full>
</body>
</html>
Loading

0 comments on commit 724d9fd

Please sign in to comment.