@eik/postcss-plugin 3.0.14 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +8 -10
- package/package.json +60 -61
- package/src/plugin.js +158 -120
- package/types/plugin.d.ts +26 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
## [4.0.1](https://github.com/eik-lib/postcss-import-map/compare/v4.0.0...v4.0.1) (2024-08-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* include type definitions ([7ad7a16](https://github.com/eik-lib/postcss-import-map/commit/7ad7a16ea7f4ca246383cf1b8797f45b0dd2995d))
|
|
7
|
+
|
|
8
|
+
# [4.0.0](https://github.com/eik-lib/postcss-import-map/compare/v3.0.14...v4.0.0) (2024-07-29)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Code Refactoring
|
|
12
|
+
|
|
13
|
+
* migrate to esm ([4e8bc12](https://github.com/eik-lib/postcss-import-map/commit/4e8bc1299323afb2ee7e74eb4d97d85869f5c904))
|
|
14
|
+
* remove node-fetch dependency ([8113805](https://github.com/eik-lib/postcss-import-map/commit/81138057c767bdecfeec96db017ddf25942e8458))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### BREAKING CHANGES
|
|
18
|
+
|
|
19
|
+
* this requires using Node 18 or newer without the
|
|
20
|
+
--no-experimental-fetch flag.
|
|
21
|
+
* module is now ESM
|
|
22
|
+
|
|
1
23
|
## [3.0.14](https://github.com/eik-lib/postcss-import-map/compare/v3.0.13...v3.0.14) (2024-03-06)
|
|
2
24
|
|
|
3
25
|
|
package/README.md
CHANGED
|
@@ -19,9 +19,7 @@ const fs = require('fs');
|
|
|
19
19
|
const css = fs.readFileSync('css/input.css', 'utf8');
|
|
20
20
|
|
|
21
21
|
postcss()
|
|
22
|
-
.use(
|
|
23
|
-
plugin()
|
|
24
|
-
)
|
|
22
|
+
.use(plugin())
|
|
25
23
|
.process(css, {
|
|
26
24
|
// `from` option is needed here
|
|
27
25
|
from: 'css/input.css',
|
|
@@ -55,8 +53,8 @@ when applaying the following Import Map:
|
|
|
55
53
|
```json
|
|
56
54
|
{
|
|
57
55
|
"imports": {
|
|
58
|
-
"normalize.css": "https://cdn.eik.dev/normalize.css@8/normalize.css"
|
|
59
|
-
}
|
|
56
|
+
"normalize.css": "https://cdn.eik.dev/normalize.css@8/normalize.css"
|
|
57
|
+
}
|
|
60
58
|
}
|
|
61
59
|
```
|
|
62
60
|
|
|
@@ -74,11 +72,11 @@ body {
|
|
|
74
72
|
|
|
75
73
|
This plugin takes the following as options:
|
|
76
74
|
|
|
77
|
-
| option
|
|
78
|
-
|
|
|
79
|
-
| path
|
|
80
|
-
| urls
|
|
81
|
-
| maps
|
|
75
|
+
| option | default | type | required | details |
|
|
76
|
+
| ------ | --------------- | -------- | -------- | ----------------------------------------------------------------------------- |
|
|
77
|
+
| path | `process.cwd()` | `string` | `false` | Path to directory containing a eik.json file or package.json with eik config. |
|
|
78
|
+
| urls | `[]` | `array` | `false` | Array of import map URLs to fetch from. |
|
|
79
|
+
| maps | `[]` | `array` | `false` | Array of import map as objects. |
|
|
82
80
|
|
|
83
81
|
The plugin will attempt to read import map URLs from [`eik.json` or `package.json`](https://eik.dev/docs/overview_eik_json) files in the root of the current working directory if present.
|
|
84
82
|
|
package/package.json
CHANGED
|
@@ -1,63 +1,62 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
2
|
+
"name": "@eik/postcss-plugin",
|
|
3
|
+
"version": "4.0.1",
|
|
4
|
+
"description": "PostCSS plugin that uses Eik defined import map files to transform bare import specifiers to absolute URLs in @import rules",
|
|
5
|
+
"main": "src/plugin.js",
|
|
6
|
+
"types": "./types/plugin.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"CHANGELOG.md",
|
|
10
|
+
"package.json",
|
|
11
|
+
"src/",
|
|
12
|
+
"types/"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "tap test/*.js --disable-coverage --allow-empty-coverage",
|
|
16
|
+
"test:snapshot": "TAP_SNAPSHOT=1 tap test/*.js --disable-coverage --allow-empty-coverage",
|
|
17
|
+
"lint": "eslint .",
|
|
18
|
+
"lint:fix": "eslint . --fix",
|
|
19
|
+
"types": "run-s types:module types:test",
|
|
20
|
+
"types:module": "tsc",
|
|
21
|
+
"types:test": "tsc --project tsconfig.test.json"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/eik-lib/postcss-import-map.git"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"css",
|
|
29
|
+
"postcss",
|
|
30
|
+
"postcss-plugin",
|
|
31
|
+
"import",
|
|
32
|
+
"url"
|
|
33
|
+
],
|
|
34
|
+
"author": "Finn.no",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/eik-lib/postcss-import-map/issues"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/eik-lib/postcss-import-map#readme",
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@eik/eslint-config": "1.0.2",
|
|
42
|
+
"@eik/prettier-config": "1.0.1",
|
|
43
|
+
"@eik/semantic-release-config": "1.0.0",
|
|
44
|
+
"@eik/typescript-config": "1.0.0",
|
|
45
|
+
"eslint": "9.8.0",
|
|
46
|
+
"fastify": "4.28.1",
|
|
47
|
+
"npm-run-all": "4.1.5",
|
|
48
|
+
"postcss": "8.4.40",
|
|
49
|
+
"prettier": "3.3.3",
|
|
50
|
+
"rollup": "4.20.0",
|
|
51
|
+
"semantic-release": "24.0.0",
|
|
52
|
+
"tap": "20.0.3",
|
|
53
|
+
"typescript": "5.5.4"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@eik/common": "4.0.7",
|
|
57
|
+
"css-url-parser": "1.1.3"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"postcss": "^8.0.0"
|
|
61
|
+
}
|
|
63
62
|
}
|
package/src/plugin.js
CHANGED
|
@@ -1,125 +1,163 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import parseCssUrls from "css-url-parser";
|
|
2
|
+
import { helpers } from "@eik/common";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {string} url
|
|
6
|
+
* @returns {boolean}
|
|
7
|
+
*/
|
|
8
|
+
const notUrl = (url) => url.substr(0, 4) !== "http";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {object} ImportMap
|
|
12
|
+
* @property {Record<string, string>} imports
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string[]} urls
|
|
17
|
+
* @returns {Promise<ImportMap[]>}
|
|
18
|
+
*/
|
|
9
19
|
async function fetchImportMaps(urls = []) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
try {
|
|
21
|
+
const maps = urls.map((map) =>
|
|
22
|
+
fetch(map).then((result) => {
|
|
23
|
+
if (result.status === 404) {
|
|
24
|
+
throw new Error("Import map could not be found on server");
|
|
25
|
+
} else if (result.status >= 400 && result.status < 500) {
|
|
26
|
+
throw new Error("Server rejected client request");
|
|
27
|
+
} else if (result.status >= 500) {
|
|
28
|
+
throw new Error("Server error");
|
|
29
|
+
}
|
|
30
|
+
return /** @type {Promise<ImportMap>} */ (result.json());
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
return await Promise.all(maps);
|
|
34
|
+
} catch (err) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Unable to load import map file from server: ${err.message}`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
29
39
|
}
|
|
30
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @param {ImportMap} map
|
|
43
|
+
* @returns {Array<{ key: string; value: string; }>}
|
|
44
|
+
*/
|
|
31
45
|
const validate = (map) =>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
46
|
+
Object.keys(map.imports).map((key) => {
|
|
47
|
+
const value = map.imports[key];
|
|
48
|
+
|
|
49
|
+
if (notUrl(value)) {
|
|
50
|
+
throw Error(
|
|
51
|
+
`Import specifier can NOT be mapped to a bare import statement. Import specifier "${key}" is being wrongly mapped to "${value}"`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { key, value };
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @typedef {object} PluginOptions
|
|
60
|
+
* @property {string} [path=process.cwd()]
|
|
61
|
+
* @property {string[]} [urls=[]] URLs to import maps hosted on an Eik server. Takes precedence over `eik.json`.
|
|
62
|
+
* @property {ImportMap[]} [maps=[]] Inline import maps that should be used. Takes precedence over `urls` and `eik.json`.
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @typedef {object} PrepareResult
|
|
67
|
+
* @property {(root: import('postcss').Root) => Promise<void>} Once
|
|
68
|
+
* @property {{ import: (decl: import('postcss').AtRule) => Promise<void> }} AtRule
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @typedef {object} Plugin
|
|
73
|
+
* @property {string} postcssPlugin
|
|
74
|
+
* @property {() => PrepareResult} prepare
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Returns the plugin which will apply the given import maps during the build.
|
|
79
|
+
* @param {PluginOptions} options
|
|
80
|
+
* @returns {Plugin}
|
|
81
|
+
*/
|
|
82
|
+
export default ({ path = process.cwd(), maps = [], urls = [] } = {}) => {
|
|
83
|
+
const pMaps = Array.isArray(maps) ? maps : [maps];
|
|
84
|
+
const pUrls = Array.isArray(urls) ? urls : [urls];
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
postcssPlugin: "@eik/postcss-import-map",
|
|
88
|
+
prepare() {
|
|
89
|
+
// Avoid parsing things more than necessary
|
|
90
|
+
const processed = new WeakMap();
|
|
91
|
+
// Only replace once per url
|
|
92
|
+
const replaced = new Set();
|
|
93
|
+
// Eagerly start resolving
|
|
94
|
+
|
|
95
|
+
// Reused replace logic
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @param {Map<string, string>} mapping
|
|
99
|
+
* @param {import('postcss').AtRule} decl
|
|
100
|
+
* @returns {void}
|
|
101
|
+
*/
|
|
102
|
+
const applyImportMap = (mapping, decl) => {
|
|
103
|
+
if (processed.has(decl)) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let key;
|
|
108
|
+
// First check if it's possibly using syntax like url()
|
|
109
|
+
const parsedUrls = parseCssUrls(decl.params);
|
|
110
|
+
if (parsedUrls.length > 0) {
|
|
111
|
+
key = parsedUrls[0];
|
|
112
|
+
} else {
|
|
113
|
+
// Handle the common cases where it's not wrapped in url() but may have quotes
|
|
114
|
+
key = decl.params.replace(/["']/g, "");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Webpack interop
|
|
118
|
+
key = key.replace(/^~/, "");
|
|
119
|
+
|
|
120
|
+
if (replaced.has(key)) {
|
|
121
|
+
decl.remove();
|
|
122
|
+
} else if (mapping.has(key)) {
|
|
123
|
+
decl.params = `'${mapping.get(key)}'`;
|
|
124
|
+
replaced.add(key);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Cache we've processed this
|
|
128
|
+
processed.set(decl, true);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/** @type {Map<string, string>} */
|
|
132
|
+
const mapping = new Map();
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
// Run initially once, this is to ensure it runs before postcss-import
|
|
136
|
+
async Once(root) {
|
|
137
|
+
// Load eik config from eik.json or package.json
|
|
138
|
+
const config = await helpers.getDefaults(path);
|
|
139
|
+
|
|
140
|
+
// Fetch import maps from the server
|
|
141
|
+
const fetched = await fetchImportMaps([...config.map, ...pUrls]);
|
|
142
|
+
|
|
143
|
+
const allImportMaps = [...fetched, ...pMaps];
|
|
144
|
+
allImportMaps.forEach((item) => {
|
|
145
|
+
const i = validate(item);
|
|
146
|
+
i.forEach((obj) => {
|
|
147
|
+
mapping.set(obj.key, obj.value);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
root.walkAtRules("import", (decl) => {
|
|
152
|
+
applyImportMap(mapping, decl);
|
|
153
|
+
});
|
|
154
|
+
},
|
|
155
|
+
AtRule: {
|
|
156
|
+
import: async (decl) => {
|
|
157
|
+
applyImportMap(mapping, decl);
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
};
|
|
123
163
|
};
|
|
124
|
-
|
|
125
|
-
module.exports.postcss = true;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
declare function _default({ path, maps, urls }?: PluginOptions): Plugin;
|
|
2
|
+
export default _default;
|
|
3
|
+
export type ImportMap = {
|
|
4
|
+
imports: Record<string, string>;
|
|
5
|
+
};
|
|
6
|
+
export type PluginOptions = {
|
|
7
|
+
path?: string;
|
|
8
|
+
/**
|
|
9
|
+
* URLs to import maps hosted on an Eik server. Takes precedence over `eik.json`.
|
|
10
|
+
*/
|
|
11
|
+
urls?: string[];
|
|
12
|
+
/**
|
|
13
|
+
* Inline import maps that should be used. Takes precedence over `urls` and `eik.json`.
|
|
14
|
+
*/
|
|
15
|
+
maps?: ImportMap[];
|
|
16
|
+
};
|
|
17
|
+
export type PrepareResult = {
|
|
18
|
+
Once: (root: import("postcss").Root) => Promise<void>;
|
|
19
|
+
AtRule: {
|
|
20
|
+
import: (decl: import("postcss").AtRule) => Promise<void>;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export type Plugin = {
|
|
24
|
+
postcssPlugin: string;
|
|
25
|
+
prepare: () => PrepareResult;
|
|
26
|
+
};
|