@atlaspack/transformer-html 2.12.1-dev.3401 → 2.12.1-dev.3450
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/lib/HTMLTransformer.js +20 -12
- package/package.json +13 -7
- package/src/HTMLTransformer.js +20 -13
- package/test/HTMLTransformer.test.js +361 -0
package/lib/HTMLTransformer.js
CHANGED
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
5
5
|
});
|
6
6
|
exports.default = void 0;
|
7
|
+
exports.parseHTML = parseHTML;
|
8
|
+
exports.transformerOpts = void 0;
|
7
9
|
function _plugin() {
|
8
10
|
const data = require("@atlaspack/plugin");
|
9
11
|
_plugin = function () {
|
@@ -56,7 +58,19 @@ function _diagnostic() {
|
|
56
58
|
return data;
|
57
59
|
}
|
58
60
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
59
|
-
|
61
|
+
function parseHTML(code, xmlMode) {
|
62
|
+
return {
|
63
|
+
type: 'posthtml',
|
64
|
+
version: '0.4.1',
|
65
|
+
program: (0, _posthtmlParser().parser)(code, {
|
66
|
+
lowerCaseTags: true,
|
67
|
+
lowerCaseAttributeNames: true,
|
68
|
+
sourceLocations: true,
|
69
|
+
xmlMode
|
70
|
+
})
|
71
|
+
};
|
72
|
+
}
|
73
|
+
const transformerOpts = exports.transformerOpts = {
|
60
74
|
canReuseAST({
|
61
75
|
ast
|
62
76
|
}) {
|
@@ -65,16 +79,9 @@ var _default = exports.default = new (_plugin().Transformer)({
|
|
65
79
|
async parse({
|
66
80
|
asset
|
67
81
|
}) {
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
program: (0, _posthtmlParser().parser)(await asset.getCode(), {
|
72
|
-
lowerCaseTags: true,
|
73
|
-
lowerCaseAttributeNames: true,
|
74
|
-
sourceLocations: true,
|
75
|
-
xmlMode: asset.type === 'xhtml'
|
76
|
-
})
|
77
|
-
};
|
82
|
+
const code = await asset.getCode();
|
83
|
+
const xmlMode = asset.type === 'xhtml';
|
84
|
+
return parseHTML(code, xmlMode);
|
78
85
|
},
|
79
86
|
async transform({
|
80
87
|
asset,
|
@@ -153,7 +160,8 @@ var _default = exports.default = new (_plugin().Transformer)({
|
|
153
160
|
})
|
154
161
|
};
|
155
162
|
}
|
156
|
-
}
|
163
|
+
};
|
164
|
+
var _default = exports.default = new (_plugin().Transformer)(transformerOpts);
|
157
165
|
function findFirstMatch(ast, expressions) {
|
158
166
|
let found;
|
159
167
|
for (const expression of expressions) {
|
package/package.json
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
{
|
2
2
|
"name": "@atlaspack/transformer-html",
|
3
|
-
"version": "2.12.1-dev.
|
4
|
-
"license": "MIT",
|
3
|
+
"version": "2.12.1-dev.3450+58845ef87",
|
4
|
+
"license": "(MIT OR Apache-2.0)",
|
5
5
|
"publishConfig": {
|
6
6
|
"access": "public"
|
7
7
|
},
|
8
|
+
"scripts": {
|
9
|
+
"test": "mocha"
|
10
|
+
},
|
8
11
|
"repository": {
|
9
12
|
"type": "git",
|
10
13
|
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
@@ -13,12 +16,12 @@
|
|
13
16
|
"source": "src/HTMLTransformer.js",
|
14
17
|
"engines": {
|
15
18
|
"node": ">= 16.0.0",
|
16
|
-
"parcel": "^2.12.1-dev.
|
19
|
+
"parcel": "^2.12.1-dev.3450+58845ef87"
|
17
20
|
},
|
18
21
|
"dependencies": {
|
19
|
-
"@atlaspack/diagnostic": "2.12.1-dev.
|
20
|
-
"@atlaspack/plugin": "2.12.1-dev.
|
21
|
-
"@atlaspack/rust": "2.12.1-dev.
|
22
|
+
"@atlaspack/diagnostic": "2.12.1-dev.3450+58845ef87",
|
23
|
+
"@atlaspack/plugin": "2.12.1-dev.3450+58845ef87",
|
24
|
+
"@atlaspack/rust": "2.12.1-dev.3450+58845ef87",
|
22
25
|
"nullthrows": "^1.1.1",
|
23
26
|
"posthtml": "^0.16.5",
|
24
27
|
"posthtml-parser": "^0.10.1",
|
@@ -26,5 +29,8 @@
|
|
26
29
|
"semver": "^7.5.2",
|
27
30
|
"srcset": "4"
|
28
31
|
},
|
29
|
-
"
|
32
|
+
"devDependencies": {
|
33
|
+
"@atlaspack/core": "2.12.1-dev.3450+58845ef87"
|
34
|
+
},
|
35
|
+
"gitHead": "58845ef87446fcedb7d7d8876440c64184645cbb"
|
30
36
|
}
|
package/src/HTMLTransformer.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
// @flow
|
2
2
|
|
3
3
|
import {Transformer} from '@atlaspack/plugin';
|
4
|
-
import type {AST} from '@atlaspack/types';
|
4
|
+
import type {AST, Transformer as TransformerOpts} from '@atlaspack/types';
|
5
5
|
import {parser as parse} from 'posthtml-parser';
|
6
6
|
import nullthrows from 'nullthrows';
|
7
7
|
import type {PostHTMLExpression, PostHTMLNode} from 'posthtml';
|
@@ -12,22 +12,28 @@ import collectDependencies from './dependencies';
|
|
12
12
|
import extractInlineAssets from './inline';
|
13
13
|
import ThrowableDiagnostic from '@atlaspack/diagnostic';
|
14
14
|
|
15
|
-
export
|
15
|
+
export function parseHTML(code: string, xmlMode: boolean): AST {
|
16
|
+
return {
|
17
|
+
type: 'posthtml',
|
18
|
+
version: '0.4.1',
|
19
|
+
program: parse(code, {
|
20
|
+
lowerCaseTags: true,
|
21
|
+
lowerCaseAttributeNames: true,
|
22
|
+
sourceLocations: true,
|
23
|
+
xmlMode,
|
24
|
+
}),
|
25
|
+
};
|
26
|
+
}
|
27
|
+
|
28
|
+
export const transformerOpts: TransformerOpts<void> = {
|
16
29
|
canReuseAST({ast}) {
|
17
30
|
return ast.type === 'posthtml' && semver.satisfies(ast.version, '^0.4.0');
|
18
31
|
},
|
19
32
|
|
20
33
|
async parse({asset}) {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
program: parse(await asset.getCode(), {
|
25
|
-
lowerCaseTags: true,
|
26
|
-
lowerCaseAttributeNames: true,
|
27
|
-
sourceLocations: true,
|
28
|
-
xmlMode: asset.type === 'xhtml',
|
29
|
-
}),
|
30
|
-
};
|
34
|
+
const code = await asset.getCode();
|
35
|
+
const xmlMode = asset.type === 'xhtml';
|
36
|
+
return parseHTML(code, xmlMode);
|
31
37
|
},
|
32
38
|
|
33
39
|
async transform({asset, options}) {
|
@@ -106,7 +112,8 @@ export default (new Transformer({
|
|
106
112
|
}),
|
107
113
|
};
|
108
114
|
},
|
109
|
-
}
|
115
|
+
};
|
116
|
+
export default (new Transformer(transformerOpts): Transformer);
|
110
117
|
|
111
118
|
function findFirstMatch(
|
112
119
|
ast: AST,
|
@@ -0,0 +1,361 @@
|
|
1
|
+
// @flow strict-local
|
2
|
+
|
3
|
+
import {type PostHTMLNode, render} from 'posthtml-render';
|
4
|
+
import {parseHTML, transformerOpts} from '../src/HTMLTransformer';
|
5
|
+
import assert from 'assert';
|
6
|
+
import type {PluginOptions} from '../../../core/types-internal/src';
|
7
|
+
|
8
|
+
function normalizeHTML(code: string): string {
|
9
|
+
const ast = parseHTML(code, true);
|
10
|
+
// $FlowFixMe
|
11
|
+
const result = renderHTML(ast);
|
12
|
+
const lines = result
|
13
|
+
.split('\n')
|
14
|
+
.map(line => line.trim())
|
15
|
+
.filter(line => line);
|
16
|
+
return lines.join('');
|
17
|
+
}
|
18
|
+
|
19
|
+
function renderHTML(newAST: {|program: PostHTMLNode|}): string {
|
20
|
+
return render(newAST.program, {
|
21
|
+
closingSingleTag: 'slash',
|
22
|
+
});
|
23
|
+
}
|
24
|
+
|
25
|
+
async function runTestTransform(
|
26
|
+
code: string,
|
27
|
+
options: {|
|
28
|
+
shouldScopeHoist: boolean,
|
29
|
+
supportsEsmodules: boolean,
|
30
|
+
hmrOptions: PluginOptions['hmrOptions'],
|
31
|
+
|} = {
|
32
|
+
shouldScopeHoist: true,
|
33
|
+
supportsEsmodules: true,
|
34
|
+
hmrOptions: null,
|
35
|
+
},
|
36
|
+
) {
|
37
|
+
const dependencies = [];
|
38
|
+
let newAST = null;
|
39
|
+
const asset = {
|
40
|
+
getAST: () => parseHTML(code, true),
|
41
|
+
setAST: n => {
|
42
|
+
newAST = n;
|
43
|
+
},
|
44
|
+
addURLDependency(url, opts) {
|
45
|
+
dependencies.push({url, opts});
|
46
|
+
return `dependency-id::${url}`;
|
47
|
+
},
|
48
|
+
env: {
|
49
|
+
shouldScopeHoist: options.shouldScopeHoist,
|
50
|
+
supports(tag: string, defaultValue: boolean) {
|
51
|
+
assert.equal(tag, 'esmodules');
|
52
|
+
assert.equal(defaultValue, true);
|
53
|
+
return options.supportsEsmodules;
|
54
|
+
},
|
55
|
+
},
|
56
|
+
addDependency(specifier, specifierType) {
|
57
|
+
dependencies.push({specifier, specifierType});
|
58
|
+
return 'dependency-id';
|
59
|
+
},
|
60
|
+
};
|
61
|
+
|
62
|
+
const transformInput = {
|
63
|
+
asset,
|
64
|
+
options: {
|
65
|
+
hmrOptions: options.hmrOptions,
|
66
|
+
},
|
67
|
+
};
|
68
|
+
// $FlowFixMe
|
69
|
+
const transformResult = await transformerOpts.transform(transformInput);
|
70
|
+
|
71
|
+
// $FlowFixMe
|
72
|
+
const outputCode = renderHTML(newAST);
|
73
|
+
|
74
|
+
return {dependencies, newAST, outputCode, transformResult, inputAsset: asset};
|
75
|
+
}
|
76
|
+
|
77
|
+
function normalizeDependencies(dependencies) {
|
78
|
+
return dependencies.map(dependency => ({
|
79
|
+
...dependency,
|
80
|
+
opts: {
|
81
|
+
...dependency.opts,
|
82
|
+
env: {
|
83
|
+
// $FlowFixMe
|
84
|
+
...dependency.opts.env,
|
85
|
+
loc: null,
|
86
|
+
},
|
87
|
+
},
|
88
|
+
}));
|
89
|
+
}
|
90
|
+
|
91
|
+
function normalizeAssets(assets) {
|
92
|
+
return assets.map(asset => {
|
93
|
+
// $FlowFixMe
|
94
|
+
return {
|
95
|
+
...asset,
|
96
|
+
env: null,
|
97
|
+
meta: null,
|
98
|
+
};
|
99
|
+
});
|
100
|
+
}
|
101
|
+
|
102
|
+
describe('HTMLTransformer', () => {
|
103
|
+
it('transform simple script tag', async () => {
|
104
|
+
const code = `
|
105
|
+
<html>
|
106
|
+
<body>
|
107
|
+
<script src="input.js"></script>
|
108
|
+
</body>
|
109
|
+
</html>
|
110
|
+
`;
|
111
|
+
const {dependencies, outputCode, transformResult, inputAsset} =
|
112
|
+
await runTestTransform(code);
|
113
|
+
assert.equal(
|
114
|
+
outputCode,
|
115
|
+
`
|
116
|
+
<html>
|
117
|
+
<body>
|
118
|
+
<script src="dependency-id::input.js"></script>
|
119
|
+
</body>
|
120
|
+
</html>
|
121
|
+
`,
|
122
|
+
);
|
123
|
+
assert.deepEqual(normalizeDependencies(dependencies), [
|
124
|
+
{
|
125
|
+
url: 'input.js',
|
126
|
+
opts: {
|
127
|
+
bundleBehavior: 'isolated',
|
128
|
+
env: {
|
129
|
+
loc: null,
|
130
|
+
outputFormat: 'global',
|
131
|
+
sourceType: 'script',
|
132
|
+
},
|
133
|
+
priority: 'parallel',
|
134
|
+
},
|
135
|
+
},
|
136
|
+
]);
|
137
|
+
|
138
|
+
assert.deepEqual(transformResult, [inputAsset]);
|
139
|
+
});
|
140
|
+
|
141
|
+
it('transforms simple inline script', async () => {
|
142
|
+
const code = `
|
143
|
+
<html>
|
144
|
+
<body>
|
145
|
+
<script>console.log('blah'); require('path');</script>
|
146
|
+
</body>
|
147
|
+
</html>
|
148
|
+
`;
|
149
|
+
const {transformResult, inputAsset} = await runTestTransform(code);
|
150
|
+
assert(transformResult.includes(inputAsset));
|
151
|
+
const assets = normalizeAssets(transformResult);
|
152
|
+
assert.deepEqual(assets[1], {
|
153
|
+
type: 'js',
|
154
|
+
content: "console.log('blah'); require('path');",
|
155
|
+
uniqueKey: 'a8a37984d2e520b9',
|
156
|
+
bundleBehavior: 'inline',
|
157
|
+
env: null,
|
158
|
+
meta: null,
|
159
|
+
});
|
160
|
+
});
|
161
|
+
|
162
|
+
it('we will get one dependency per asset', async () => {
|
163
|
+
const code = `
|
164
|
+
<html>
|
165
|
+
<body>
|
166
|
+
<script src="input1.js"></script>
|
167
|
+
<script src="input2.js"></script>
|
168
|
+
</body>
|
169
|
+
</html>
|
170
|
+
`;
|
171
|
+
const {dependencies, outputCode, transformResult, inputAsset} =
|
172
|
+
await runTestTransform(code);
|
173
|
+
assert.equal(
|
174
|
+
outputCode,
|
175
|
+
`
|
176
|
+
<html>
|
177
|
+
<body>
|
178
|
+
<script src="dependency-id::input1.js"></script>
|
179
|
+
<script src="dependency-id::input2.js"></script>
|
180
|
+
</body>
|
181
|
+
</html>
|
182
|
+
`,
|
183
|
+
);
|
184
|
+
const opts = {
|
185
|
+
bundleBehavior: 'isolated',
|
186
|
+
env: {
|
187
|
+
loc: null,
|
188
|
+
outputFormat: 'global',
|
189
|
+
sourceType: 'script',
|
190
|
+
},
|
191
|
+
priority: 'parallel',
|
192
|
+
};
|
193
|
+
assert.deepEqual(normalizeDependencies(dependencies), [
|
194
|
+
{
|
195
|
+
url: 'input1.js',
|
196
|
+
opts,
|
197
|
+
},
|
198
|
+
{
|
199
|
+
url: 'input2.js',
|
200
|
+
opts,
|
201
|
+
},
|
202
|
+
]);
|
203
|
+
|
204
|
+
assert.deepEqual(transformResult, [inputAsset]);
|
205
|
+
});
|
206
|
+
|
207
|
+
it('transform simple module tag', async () => {
|
208
|
+
const code = `
|
209
|
+
<html>
|
210
|
+
<body>
|
211
|
+
<script src="input.js" type="module"></script>
|
212
|
+
</body>
|
213
|
+
</html>
|
214
|
+
`;
|
215
|
+
const {dependencies, outputCode, transformResult, inputAsset} =
|
216
|
+
await runTestTransform(code);
|
217
|
+
assert.equal(
|
218
|
+
outputCode,
|
219
|
+
`
|
220
|
+
<html>
|
221
|
+
<body>
|
222
|
+
<script src="dependency-id::input.js" type="module"></script>
|
223
|
+
</body>
|
224
|
+
</html>
|
225
|
+
`,
|
226
|
+
);
|
227
|
+
assert.deepEqual(normalizeDependencies(dependencies), [
|
228
|
+
{
|
229
|
+
url: 'input.js',
|
230
|
+
opts: {
|
231
|
+
bundleBehavior: undefined,
|
232
|
+
env: {
|
233
|
+
loc: null,
|
234
|
+
outputFormat: 'esmodule',
|
235
|
+
sourceType: 'module',
|
236
|
+
},
|
237
|
+
priority: 'parallel',
|
238
|
+
},
|
239
|
+
},
|
240
|
+
]);
|
241
|
+
|
242
|
+
assert.deepEqual(transformResult, [inputAsset]);
|
243
|
+
});
|
244
|
+
|
245
|
+
it('transform simple module tag if there is no support for esmodules', async () => {
|
246
|
+
const code = `
|
247
|
+
<html>
|
248
|
+
<body>
|
249
|
+
<script src="input.js" type="module"></script>
|
250
|
+
</body>
|
251
|
+
</html>
|
252
|
+
`;
|
253
|
+
const {dependencies, outputCode, transformResult, inputAsset} =
|
254
|
+
await runTestTransform(code, {
|
255
|
+
shouldScopeHoist: true,
|
256
|
+
supportsEsmodules: false,
|
257
|
+
hmrOptions: null,
|
258
|
+
});
|
259
|
+
assert.equal(
|
260
|
+
normalizeHTML(outputCode),
|
261
|
+
normalizeHTML(`
|
262
|
+
<html>
|
263
|
+
<body>
|
264
|
+
<script src="dependency-id::input.js" type="module"></script>
|
265
|
+
<script src="dependency-id::input.js" nomodule="" defer=""></script>
|
266
|
+
</body>
|
267
|
+
</html>
|
268
|
+
`),
|
269
|
+
);
|
270
|
+
assert.deepEqual(normalizeDependencies(dependencies), [
|
271
|
+
{
|
272
|
+
url: 'input.js',
|
273
|
+
opts: {
|
274
|
+
bundleBehavior: undefined,
|
275
|
+
env: {
|
276
|
+
loc: null,
|
277
|
+
outputFormat: 'global',
|
278
|
+
sourceType: 'module',
|
279
|
+
},
|
280
|
+
priority: 'parallel',
|
281
|
+
},
|
282
|
+
},
|
283
|
+
{
|
284
|
+
url: 'input.js',
|
285
|
+
opts: {
|
286
|
+
bundleBehavior: undefined,
|
287
|
+
env: {
|
288
|
+
loc: null,
|
289
|
+
outputFormat: 'esmodule',
|
290
|
+
sourceType: 'module',
|
291
|
+
},
|
292
|
+
priority: 'parallel',
|
293
|
+
},
|
294
|
+
},
|
295
|
+
]);
|
296
|
+
|
297
|
+
assert.deepEqual(transformResult, [inputAsset]);
|
298
|
+
});
|
299
|
+
|
300
|
+
it('adds an HMR tag if there are HMR options set', async () => {
|
301
|
+
const code = `
|
302
|
+
<html>
|
303
|
+
<body>
|
304
|
+
<script src="input.js"></script>
|
305
|
+
</body>
|
306
|
+
</html>
|
307
|
+
`;
|
308
|
+
const {dependencies, outputCode, transformResult, inputAsset} =
|
309
|
+
await runTestTransform(code, {
|
310
|
+
shouldScopeHoist: true,
|
311
|
+
supportsEsmodules: true,
|
312
|
+
hmrOptions: {
|
313
|
+
port: 1234,
|
314
|
+
host: 'localhost',
|
315
|
+
},
|
316
|
+
});
|
317
|
+
assert.equal(
|
318
|
+
normalizeHTML(outputCode),
|
319
|
+
normalizeHTML(`
|
320
|
+
<html>
|
321
|
+
<body>
|
322
|
+
<script src="dependency-id::input.js"></script>
|
323
|
+
<script src="dependency-id::hmr.js"></script>
|
324
|
+
</body>
|
325
|
+
</html>
|
326
|
+
`),
|
327
|
+
);
|
328
|
+
assert.deepEqual(normalizeDependencies(dependencies), [
|
329
|
+
{
|
330
|
+
url: 'input.js',
|
331
|
+
opts: {
|
332
|
+
bundleBehavior: 'isolated',
|
333
|
+
env: {
|
334
|
+
loc: null,
|
335
|
+
outputFormat: 'global',
|
336
|
+
sourceType: 'script',
|
337
|
+
},
|
338
|
+
priority: 'parallel',
|
339
|
+
},
|
340
|
+
},
|
341
|
+
{
|
342
|
+
url: 'hmr.js',
|
343
|
+
opts: {
|
344
|
+
env: {
|
345
|
+
loc: null,
|
346
|
+
},
|
347
|
+
priority: 'parallel',
|
348
|
+
},
|
349
|
+
},
|
350
|
+
]);
|
351
|
+
|
352
|
+
assert.deepEqual(transformResult, [
|
353
|
+
inputAsset,
|
354
|
+
{
|
355
|
+
content: '',
|
356
|
+
type: 'js',
|
357
|
+
uniqueKey: 'hmr.js',
|
358
|
+
},
|
359
|
+
]);
|
360
|
+
});
|
361
|
+
});
|