@eik/postcss-plugin 3.0.0-next.1 → 3.0.2
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 +54 -0
- package/README.md +110 -79
- package/package.json +17 -21
- package/src/plugin.js +121 -0
- package/dist/plugin.js +0 -157
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,57 @@
|
|
|
1
|
+
## [3.0.2](https://github.com/eik-lib/postcss-import-map/compare/v3.0.1...v3.0.2) (2021-09-21)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **deps:** update dependency node-fetch to v2.6.3 ([7d74f72](https://github.com/eik-lib/postcss-import-map/commit/7d74f72e111b127189158da8cfdce838292ca7c6))
|
|
7
|
+
|
|
8
|
+
## [3.0.1](https://github.com/eik-lib/postcss-import-map/compare/v3.0.0...v3.0.1) (2021-09-06)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **deps:** update dependency node-fetch to v2.6.2 ([fcf0ae5](https://github.com/eik-lib/postcss-import-map/commit/fcf0ae5659a7f0ace755b7e36d10c6d52fd3621c))
|
|
14
|
+
|
|
15
|
+
# [3.0.0](https://github.com/eik-lib/postcss-import-map/compare/v2.0.4...v3.0.0) (2021-08-13)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* Rename module to @eik/postcss-plugin ([#83](https://github.com/eik-lib/postcss-import-map/issues/83)) ([7efa758](https://github.com/eik-lib/postcss-import-map/commit/7efa758f4dc8162e4ca500a7628d7c80f4151b61))
|
|
21
|
+
* Use @eik/common to load config in a project ([#84](https://github.com/eik-lib/postcss-import-map/issues/84)) ([371dcda](https://github.com/eik-lib/postcss-import-map/commit/371dcda2c5245c3759ee4c45e27fc64f926f88fc))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### BREAKING CHANGES
|
|
25
|
+
|
|
26
|
+
* Use logic in @eik/common to load config from eik.json or package.json
|
|
27
|
+
|
|
28
|
+
* chore: Adjust for PR comments
|
|
29
|
+
|
|
30
|
+
* chore: Remove extra whitespace
|
|
31
|
+
|
|
32
|
+
Co-authored-by: Trygve Lie <trygve.lie@finn.no>
|
|
33
|
+
* Rename module to @eik/postcss-plugin
|
|
34
|
+
|
|
35
|
+
Co-authored-by: Trygve Lie <trygve.lie@finn.no>
|
|
36
|
+
|
|
37
|
+
# [3.0.0-next.2](https://github.com/eik-lib/postcss-import-map/compare/v3.0.0-next.1...v3.0.0-next.2) (2021-03-02)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
### Features
|
|
41
|
+
|
|
42
|
+
* Use @eik/common to load config in a project ([#84](https://github.com/eik-lib/postcss-import-map/issues/84)) ([371dcda](https://github.com/eik-lib/postcss-import-map/commit/371dcda2c5245c3759ee4c45e27fc64f926f88fc))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### BREAKING CHANGES
|
|
46
|
+
|
|
47
|
+
* Use logic in @eik/common to load config from eik.json or package.json
|
|
48
|
+
|
|
49
|
+
* chore: Adjust for PR comments
|
|
50
|
+
|
|
51
|
+
* chore: Remove extra whitespace
|
|
52
|
+
|
|
53
|
+
Co-authored-by: Trygve Lie <trygve.lie@finn.no>
|
|
54
|
+
|
|
1
55
|
# [3.0.0-next.1](https://github.com/eik-lib/postcss-import-map/compare/v2.0.4...v3.0.0-next.1) (2021-02-18)
|
|
2
56
|
|
|
3
57
|
|
package/README.md
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
# postcss-
|
|
1
|
+
# @eik/postcss-plugin
|
|
2
2
|
|
|
3
3
|
PostCSS [Eik](https://eik.dev/) plugin to support the use of import maps to map "bare" import specifiers in CSS @import rules.
|
|
4
4
|
|
|
5
|
-
**Notes:**
|
|
6
|
-
|
|
7
|
-
- **This plugin should probably be used as the first plugin of your list.**
|
|
8
|
-
- **If you use `postcss-import` please [read this.](#postcss-import-usage)**
|
|
9
|
-
|
|
10
5
|
## Installation
|
|
11
6
|
|
|
12
7
|
```bash
|
|
@@ -16,36 +11,36 @@ $ npm install @eik/postcss-plugin
|
|
|
16
11
|
## Usage
|
|
17
12
|
|
|
18
13
|
```js
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
var plugin = require('@eik/postcss-plugin');
|
|
14
|
+
const postcss = require('postcss');
|
|
15
|
+
const plugin = require('@eik/postcss-plugin');
|
|
16
|
+
const fs = require('fs');
|
|
23
17
|
|
|
24
|
-
//
|
|
25
|
-
|
|
18
|
+
// CSS to be processed
|
|
19
|
+
const css = fs.readFileSync('css/input.css', 'utf8');
|
|
26
20
|
|
|
27
|
-
// process css
|
|
28
21
|
postcss()
|
|
29
22
|
.use(
|
|
30
|
-
plugin(
|
|
31
|
-
imports: {
|
|
32
|
-
'normalize.css':
|
|
33
|
-
'https://unpkg.com/normalize.css@8/normalize.css',
|
|
34
|
-
},
|
|
35
|
-
})
|
|
23
|
+
plugin()
|
|
36
24
|
)
|
|
37
25
|
.process(css, {
|
|
38
26
|
// `from` option is needed here
|
|
39
27
|
from: 'css/input.css',
|
|
40
28
|
})
|
|
41
29
|
.then(function (result) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
console.log(output);
|
|
30
|
+
console.log(result.css);
|
|
45
31
|
});
|
|
46
32
|
```
|
|
47
33
|
|
|
48
|
-
|
|
34
|
+
## Description
|
|
35
|
+
|
|
36
|
+
This plugin transforms "bare" import specifiers to absolute URL specifiers in
|
|
37
|
+
CSS modules by applying an Import Map ahead of time.
|
|
38
|
+
|
|
39
|
+
For a more detailed description of Import Maps, please see our [Import Maps section](https://eik.dev/docs/mapping_import_map).
|
|
40
|
+
|
|
41
|
+
The main target for Import Maps is to map import statements in EcmaScript Modules but it can be applied to CSS import statements too.
|
|
42
|
+
|
|
43
|
+
Given the following CSS:
|
|
49
44
|
|
|
50
45
|
```css
|
|
51
46
|
@import 'normalize.css';
|
|
@@ -55,92 +50,128 @@ body {
|
|
|
55
50
|
}
|
|
56
51
|
```
|
|
57
52
|
|
|
58
|
-
|
|
53
|
+
when applaying the following Import Map:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"imports": {
|
|
58
|
+
"normalize.css": "https://cdn.eik.dev/normalize.css@8/normalize.css",
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
one will get a transformed CSS like so:
|
|
59
64
|
|
|
60
65
|
```css
|
|
61
|
-
@import 'https://
|
|
66
|
+
@import 'https://cdn.eik.dev/normalize.css@8/normalize.css';
|
|
62
67
|
|
|
63
68
|
body {
|
|
64
69
|
background: black;
|
|
65
70
|
}
|
|
66
71
|
```
|
|
67
72
|
|
|
68
|
-
##
|
|
73
|
+
## Options
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
|
|
75
|
+
This plugin takes the following as options:
|
|
76
|
+
|
|
77
|
+
| option | default | type | required | details |
|
|
78
|
+
| ------- | --------------- | -------- | -------- | ----------------------------------------------------------------------------- |
|
|
79
|
+
| path | `process.cwd()` | `string` | `false` | Path to directory containing a eik.json file or package.json with eik config. |
|
|
80
|
+
| urls | `[]` | `array` | `false` | Array of import map URLs to fetch from. |
|
|
81
|
+
| maps | `[]` | `array` | `false` | Array of import map as objects. |
|
|
82
|
+
|
|
83
|
+
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.
|
|
72
84
|
|
|
73
85
|
```js
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}),
|
|
81
|
-
],
|
|
82
|
-
});
|
|
86
|
+
postcss()
|
|
87
|
+
.use(
|
|
88
|
+
plugin()
|
|
89
|
+
)
|
|
90
|
+
.process(css, {...})
|
|
91
|
+
.then(...);
|
|
83
92
|
```
|
|
84
93
|
|
|
85
|
-
|
|
94
|
+
The path to the location of an `eik.json` file can be specified with the `path` option.
|
|
86
95
|
|
|
87
|
-
|
|
96
|
+
```js
|
|
97
|
+
postcss()
|
|
98
|
+
.use(
|
|
99
|
+
plugin({ path: '/path/to/eik-json-folder' })
|
|
100
|
+
)
|
|
101
|
+
.process(css, {...})
|
|
102
|
+
.then(...);
|
|
103
|
+
```
|
|
88
104
|
|
|
89
|
-
The
|
|
90
|
-
`path` defaults to the current working directory.
|
|
105
|
+
The plugin can also be told which URLs to load import maps from directly using the `urls` option.
|
|
91
106
|
|
|
92
107
|
```js
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
postcss()
|
|
109
|
+
.use(
|
|
110
|
+
plugin({ urls: 'http://myserver/import-map' })
|
|
111
|
+
)
|
|
112
|
+
.process(css, {...})
|
|
113
|
+
.then(...);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Additionally, individual mappings can be specified using the `maps` option.
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
postcss()
|
|
120
|
+
.use(
|
|
121
|
+
plugin({
|
|
122
|
+
maps: [{
|
|
123
|
+
"imports": {
|
|
124
|
+
"normalize.css": "https://cdn.eik.dev/normalize.css@8/normalize.css",
|
|
125
|
+
},
|
|
126
|
+
}],
|
|
127
|
+
})
|
|
128
|
+
)
|
|
129
|
+
.process(css, {...})
|
|
130
|
+
.then(...);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Precedence
|
|
134
|
+
|
|
135
|
+
If several of the options are used, `maps` takes precedence over `urls` which takes precedence over values loaded from an `eik.json` or `package.json` file.
|
|
136
|
+
|
|
137
|
+
ie. in the following example
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
postcss()
|
|
141
|
+
.use(
|
|
142
|
+
plugin({
|
|
143
|
+
path: '/path/to/eik-json-folder',
|
|
144
|
+
urls: ['http://myserver/import-map'],
|
|
145
|
+
maps: [{
|
|
146
|
+
"imports": {
|
|
147
|
+
"normalize.css": "https://cdn.eik.dev/normalize.css@8/normalize.css",
|
|
148
|
+
},
|
|
149
|
+
}],
|
|
150
|
+
})
|
|
151
|
+
)
|
|
152
|
+
.process(css, {...})
|
|
153
|
+
.then(...);
|
|
106
154
|
```
|
|
107
155
|
|
|
108
|
-
|
|
109
|
-
|
|
156
|
+
Any import map URLs in `eik.json` will be loaded first, then merged with (and overridden if necessary by) the result of fetching from `http://myserver/import-map` before finally being merged with (and overriden if necessary by) specific mappings defined in `maps`.
|
|
157
|
+
|
|
158
|
+
## PostCSS Import Usage
|
|
159
|
+
|
|
160
|
+
If you're using [postcss-import](https://github.com/postcss/postcss-import) make sure you update the `plugins` option.
|
|
161
|
+
`postcss.config.js`
|
|
110
162
|
|
|
111
163
|
```js
|
|
112
164
|
module.exports = (ctx) => ({
|
|
113
165
|
plugins: [
|
|
114
|
-
require('@eik/postcss-plugin')(
|
|
115
|
-
packagePath: '/path/to/package.json',
|
|
116
|
-
}),
|
|
166
|
+
require('@eik/postcss-plugin')(),
|
|
117
167
|
require('postcss-import')({
|
|
118
168
|
// It needs to be added here as well to ensure everything is mapped
|
|
119
|
-
plugins: [
|
|
120
|
-
require('@eik/postcss-plugin')({
|
|
121
|
-
packagePath: '/path/to/package.json',
|
|
122
|
-
}),
|
|
123
|
-
],
|
|
169
|
+
plugins: [require('@eik/postcss-plugin')],
|
|
124
170
|
}),
|
|
125
171
|
],
|
|
126
172
|
});
|
|
127
173
|
```
|
|
128
174
|
|
|
129
|
-
## Options
|
|
130
|
-
|
|
131
|
-
This plugin takes an [import map](https://github.com/WICG/import-maps) as options:
|
|
132
|
-
|
|
133
|
-
| option | default | type | required | details |
|
|
134
|
-
| ----------- | ------------------ | -------- | -------- | ----------------------------------------------------------- |
|
|
135
|
-
| path | `cwd/eik.json` | `string` | `false` | Path to eik.json file. |
|
|
136
|
-
| packagePath | `cwd/package.json` | `string` | `false` | Path to package.json file. |
|
|
137
|
-
| urls | `[]` | `array` | `false` | Array of import map URLs to fetch from. |
|
|
138
|
-
| imports | `{}` | `object` | `false` | Mapping between "bare" import specifiers and absolute URLs. |
|
|
139
|
-
|
|
140
|
-
This module only cares about "bare" import specifies which map to absolute
|
|
141
|
-
URLs in the import map. Any other import specifiers defined in the import map
|
|
142
|
-
are ignored.
|
|
143
|
-
|
|
144
175
|
## License
|
|
145
176
|
|
|
146
177
|
Copyright (c) 2020 Finn.no
|
package/package.json
CHANGED
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eik/postcss-plugin",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "PostCSS plugin that uses Eik defined import map files to transform bare import specifiers to absolute URLs in @import rules",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "src/plugin.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"CHANGELOG.md",
|
|
8
8
|
"package.json",
|
|
9
|
-
"
|
|
9
|
+
"src/"
|
|
10
10
|
],
|
|
11
|
-
"directories": {
|
|
12
|
-
"dist": "dist"
|
|
13
|
-
},
|
|
14
11
|
"scripts": {
|
|
15
|
-
"prepare": "npm run -s build",
|
|
16
12
|
"test": "tap test/*.js --no-coverage",
|
|
17
13
|
"test:snapshot": "TAP_SNAPSHOT=1 tap test/*.js --no-coverage",
|
|
18
14
|
"lint": "eslint .",
|
|
19
|
-
"lint:fix": "eslint . --fix"
|
|
20
|
-
"build": "rollup -c"
|
|
15
|
+
"lint:fix": "eslint . --fix"
|
|
21
16
|
},
|
|
22
17
|
"repository": {
|
|
23
18
|
"type": "git",
|
|
@@ -39,23 +34,24 @@
|
|
|
39
34
|
"devDependencies": {
|
|
40
35
|
"@semantic-release/changelog": "5.0.1",
|
|
41
36
|
"@semantic-release/commit-analyzer": "8.0.1",
|
|
42
|
-
"@semantic-release/git": "9.0.
|
|
43
|
-
"@semantic-release/github": "7.2.
|
|
44
|
-
"@semantic-release/npm": "7.
|
|
45
|
-
"@semantic-release/release-notes-generator": "9.0.
|
|
46
|
-
"eslint": "7.
|
|
37
|
+
"@semantic-release/git": "9.0.1",
|
|
38
|
+
"@semantic-release/github": "7.2.3",
|
|
39
|
+
"@semantic-release/npm": "7.1.3",
|
|
40
|
+
"@semantic-release/release-notes-generator": "9.0.3",
|
|
41
|
+
"eslint": "7.32.0",
|
|
47
42
|
"eslint-config-airbnb-base": "14.2.1",
|
|
48
|
-
"eslint-plugin-import": "2.
|
|
49
|
-
"eslint-config-prettier": "
|
|
50
|
-
"fastify": "3.
|
|
51
|
-
"postcss": "8.
|
|
52
|
-
"rollup": "2.
|
|
53
|
-
"semantic-release": "17.
|
|
43
|
+
"eslint-plugin-import": "2.24.2",
|
|
44
|
+
"eslint-config-prettier": "8.3.0",
|
|
45
|
+
"fastify": "3.21.3",
|
|
46
|
+
"postcss": "8.3.6",
|
|
47
|
+
"rollup": "2.56.3",
|
|
48
|
+
"semantic-release": "17.4.7",
|
|
54
49
|
"tap": "14.11.0"
|
|
55
50
|
},
|
|
56
51
|
"dependencies": {
|
|
52
|
+
"@eik/common": "4.0.0-next.4",
|
|
57
53
|
"css-url-parser": "1.1.3",
|
|
58
|
-
"node-fetch": "2.6.
|
|
54
|
+
"node-fetch": "2.6.3"
|
|
59
55
|
},
|
|
60
56
|
"peerDependencies": {
|
|
61
57
|
"postcss": "^8.0.0"
|
package/src/plugin.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-syntax, no-shadow */
|
|
2
|
+
|
|
3
|
+
const parseCssUrls = require('css-url-parser');
|
|
4
|
+
const { helpers } = require('@eik/common');
|
|
5
|
+
const fetch = require('node-fetch');
|
|
6
|
+
|
|
7
|
+
const notUrl = (url) => url.substr(0, 4) !== 'http';
|
|
8
|
+
|
|
9
|
+
async function fetchImportMaps(urls = []) {
|
|
10
|
+
try {
|
|
11
|
+
const maps = urls.map((map) => fetch(map).then((result) => {
|
|
12
|
+
if (result.status === 404) {
|
|
13
|
+
throw new Error('Import map could not be found on server');
|
|
14
|
+
} else if (result.status >= 400 && result.status < 500) {
|
|
15
|
+
throw new Error('Server rejected client request');
|
|
16
|
+
} else if (result.status >= 500) {
|
|
17
|
+
throw new Error('Server error');
|
|
18
|
+
}
|
|
19
|
+
return result.json();
|
|
20
|
+
}));
|
|
21
|
+
return await Promise.all(maps);
|
|
22
|
+
} catch (err) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Unable to load import map file from server: ${err.message}`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const validate = (map) => Object.keys(map.imports).map((key) => {
|
|
30
|
+
const value = map.imports[key];
|
|
31
|
+
|
|
32
|
+
if (notUrl(value)) {
|
|
33
|
+
throw Error(`Import specifier can NOT be mapped to a bare import statement. Import specifier "${key}" is being wrongly mapped to "${value}"`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return { key, value };
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
module.exports = ({
|
|
40
|
+
path = process.cwd(),
|
|
41
|
+
maps = [],
|
|
42
|
+
urls = [],
|
|
43
|
+
} = {}) => {
|
|
44
|
+
const pMaps = Array.isArray(maps) ? maps : [maps];
|
|
45
|
+
const pUrls = Array.isArray(urls) ? urls : [urls];
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
postcssPlugin: '@eik/postcss-import-map',
|
|
49
|
+
prepare() {
|
|
50
|
+
// Avoid parsing things more than necessary
|
|
51
|
+
const processed = new WeakMap();
|
|
52
|
+
// Only replace once per url
|
|
53
|
+
const replaced = new Set();
|
|
54
|
+
// Eagerly start resolving
|
|
55
|
+
|
|
56
|
+
// Reused replace logic
|
|
57
|
+
const applyImportMap = (mapping, decl) => {
|
|
58
|
+
if (processed.has(decl)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let key;
|
|
63
|
+
// First check if it's possibly using syntax like url()
|
|
64
|
+
const parsedUrls = parseCssUrls(decl.params);
|
|
65
|
+
if (parsedUrls.length > 0) {
|
|
66
|
+
// eslint-disable-next-line prefer-destructuring
|
|
67
|
+
key = parsedUrls[0];
|
|
68
|
+
} else {
|
|
69
|
+
// Handle the common cases where it's not wrapped in url() but may have quotes
|
|
70
|
+
key = decl.params.replace(/["']/g, '');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Webpack interop
|
|
74
|
+
key = key.replace(/^~/, '');
|
|
75
|
+
|
|
76
|
+
if (replaced.has(key)) {
|
|
77
|
+
decl.remove();
|
|
78
|
+
} else if (mapping.has(key)) {
|
|
79
|
+
// eslint-disable-next-line no-param-reassign
|
|
80
|
+
decl.params = `'${mapping.get(key)}'`;
|
|
81
|
+
replaced.add(key);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Cache we've processed this
|
|
85
|
+
processed.set(decl, true);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const mapping = new Map();
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
// Run initially once, this is to ensure it runs before postcss-import
|
|
92
|
+
async Once(root) {
|
|
93
|
+
// Load eik config from eik.json or package.json
|
|
94
|
+
const config = await helpers.getDefaults(path);
|
|
95
|
+
|
|
96
|
+
// Fetch import maps from the server
|
|
97
|
+
const fetched = await fetchImportMaps([...config.map, ...pUrls]);
|
|
98
|
+
|
|
99
|
+
const allImportMaps = [...fetched, ...pMaps];
|
|
100
|
+
allImportMaps.forEach((item) => {
|
|
101
|
+
const i = validate(item);
|
|
102
|
+
i.forEach((obj) => {
|
|
103
|
+
mapping.set(obj.key, obj.value);
|
|
104
|
+
});
|
|
105
|
+
});;
|
|
106
|
+
|
|
107
|
+
root.walkAtRules('import', (decl) => {
|
|
108
|
+
applyImportMap(mapping, decl);
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
AtRule: {
|
|
112
|
+
import: async (decl) => {
|
|
113
|
+
applyImportMap(mapping, decl);
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
module.exports.postcss = true;
|
package/dist/plugin.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/* eslint-disable no-restricted-syntax, no-shadow */
|
|
4
|
-
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const fetch = require('node-fetch');
|
|
8
|
-
const parseCssUrls = require('css-url-parser');
|
|
9
|
-
|
|
10
|
-
const notUrl = (url) => url.substr(0, 4) !== 'http';
|
|
11
|
-
|
|
12
|
-
const notBare = (str) =>
|
|
13
|
-
str.startsWith('/') || str.startsWith('./') || str.startsWith('../');
|
|
14
|
-
|
|
15
|
-
async function readJSONFile(path) {
|
|
16
|
-
try {
|
|
17
|
-
const contents = await fs.promises.readFile(path);
|
|
18
|
-
return JSON.parse(contents);
|
|
19
|
-
} catch (err) {
|
|
20
|
-
return {};
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function readEikJSONMaps(eikJSONPath, pkgJSONPath) {
|
|
25
|
-
const eikJSON = await readJSONFile(eikJSONPath);
|
|
26
|
-
const pkgJSON = await readJSONFile(pkgJSONPath);
|
|
27
|
-
|
|
28
|
-
if (eikJSON.name && pkgJSON.eik) {
|
|
29
|
-
throw new Error('Eik configuration was defined in both in package.json and eik.json. You must specify one or the other.');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const config = { ...eikJSON, ...pkgJSON.eik };
|
|
33
|
-
|
|
34
|
-
if (typeof config['import-map'] === 'string') return [config['import-map']];
|
|
35
|
-
return config['import-map'] || [];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function fetchImportMaps(urls = []) {
|
|
39
|
-
try {
|
|
40
|
-
const maps = urls.map((map) =>
|
|
41
|
-
fetch(map).then((result) => {
|
|
42
|
-
if (result.status === 404) {
|
|
43
|
-
throw new Error('Import map could not be found on server');
|
|
44
|
-
} else if (result.status >= 400 && result.status < 500) {
|
|
45
|
-
throw new Error('Server rejected client request');
|
|
46
|
-
} else if (result.status >= 500) {
|
|
47
|
-
throw new Error('Server error');
|
|
48
|
-
}
|
|
49
|
-
return result.json();
|
|
50
|
-
})
|
|
51
|
-
);
|
|
52
|
-
const results = await Promise.all(maps);
|
|
53
|
-
const dependencies = results.map((result) => result.imports);
|
|
54
|
-
return Object.assign({}, ...dependencies);
|
|
55
|
-
} catch (err) {
|
|
56
|
-
throw new Error(
|
|
57
|
-
`Unable to load import map file from server: ${err.message}`
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// @TODO this could be a @eik/import-map-utils package
|
|
63
|
-
async function populateImportMap({
|
|
64
|
-
path: eikPath = path.join(process.cwd(), 'eik.json'),
|
|
65
|
-
packagePath = path.join(process.cwd(), 'package.json'),
|
|
66
|
-
urls = [],
|
|
67
|
-
imports = {},
|
|
68
|
-
} = {}) {
|
|
69
|
-
const mapping = new Map();
|
|
70
|
-
|
|
71
|
-
const importmapUrls = await readEikJSONMaps(eikPath, packagePath);
|
|
72
|
-
for (const map of importmapUrls) {
|
|
73
|
-
urls.push(map);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
let imprts = {};
|
|
77
|
-
if (urls.length > 0) {
|
|
78
|
-
imprts = { ...(await fetchImportMaps(urls)) };
|
|
79
|
-
}
|
|
80
|
-
Object.assign(imprts, imports);
|
|
81
|
-
|
|
82
|
-
Object.keys(imprts).forEach((key) => {
|
|
83
|
-
const value = Array.isArray(imprts[key]) ? imprts[key][0] : imprts[key];
|
|
84
|
-
|
|
85
|
-
if (notBare(key)) return;
|
|
86
|
-
|
|
87
|
-
if (notUrl(value))
|
|
88
|
-
throw Error('Target for import specifier must be an absolute URL.');
|
|
89
|
-
|
|
90
|
-
mapping.set(key, value);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
return mapping;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
module.exports = ({ path, packagePath, urls, imports } = {}) => {
|
|
97
|
-
return {
|
|
98
|
-
postcssPlugin: '@eik/postcss-import-map',
|
|
99
|
-
prepare() {
|
|
100
|
-
// Avoid parsing things more than necessary
|
|
101
|
-
const processed = new WeakMap();
|
|
102
|
-
// Only replace once per url
|
|
103
|
-
const replaced = new Set();
|
|
104
|
-
// Eagerly start resolving
|
|
105
|
-
const mapFetch = populateImportMap({ path, packagePath, urls, imports });
|
|
106
|
-
// Reused replace logic
|
|
107
|
-
const applyImportMap = (mapping, decl) => {
|
|
108
|
-
if (processed.has(decl)) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
let key;
|
|
113
|
-
// First check if it's possibly using syntax like url()
|
|
114
|
-
const parsedUrls = parseCssUrls(decl.params);
|
|
115
|
-
if (parsedUrls.length > 0) {
|
|
116
|
-
// eslint-disable-next-line prefer-destructuring
|
|
117
|
-
key = parsedUrls[0];
|
|
118
|
-
} else {
|
|
119
|
-
// Handle the common cases where it's not wrapped in url() but may have quotes
|
|
120
|
-
key = decl.params.replace(/["']/g, '');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Webpack interop
|
|
124
|
-
key = key.replace(/^~/, '');
|
|
125
|
-
|
|
126
|
-
if (replaced.has(key)) {
|
|
127
|
-
decl.remove();
|
|
128
|
-
} else if (mapping.has(key)) {
|
|
129
|
-
// eslint-disable-next-line no-param-reassign
|
|
130
|
-
decl.params = `'${mapping.get(key)}'`;
|
|
131
|
-
replaced.add(key);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Cache we've processed this
|
|
135
|
-
processed.set(decl, true);
|
|
136
|
-
};
|
|
137
|
-
return {
|
|
138
|
-
// Run initially once, this is to ensure it runs before postcss-import
|
|
139
|
-
async Once(root) {
|
|
140
|
-
const mapping = await mapFetch;
|
|
141
|
-
|
|
142
|
-
root.walkAtRules('import', (decl) => {
|
|
143
|
-
applyImportMap(mapping, decl);
|
|
144
|
-
});
|
|
145
|
-
},
|
|
146
|
-
AtRule: {
|
|
147
|
-
import: async (decl) => {
|
|
148
|
-
const mapping = await mapFetch;
|
|
149
|
-
applyImportMap(mapping, decl);
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
};
|
|
153
|
-
},
|
|
154
|
-
};
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
module.exports.postcss = true;
|