@atlaspack/transformer-html 2.12.1-dev.3401 → 2.12.1-dev.3443

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.
@@ -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
- var _default = exports.default = new (_plugin().Transformer)({
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
- return {
69
- type: 'posthtml',
70
- version: '0.4.1',
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.3401+b483af77f",
4
- "license": "MIT",
3
+ "version": "2.12.1-dev.3443+d1170cfc7",
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.3401+b483af77f"
19
+ "parcel": "^2.12.1-dev.3443+d1170cfc7"
17
20
  },
18
21
  "dependencies": {
19
- "@atlaspack/diagnostic": "2.12.1-dev.3401+b483af77f",
20
- "@atlaspack/plugin": "2.12.1-dev.3401+b483af77f",
21
- "@atlaspack/rust": "2.12.1-dev.3401+b483af77f",
22
+ "@atlaspack/diagnostic": "2.12.1-dev.3443+d1170cfc7",
23
+ "@atlaspack/plugin": "2.12.1-dev.3443+d1170cfc7",
24
+ "@atlaspack/rust": "2.12.1-dev.3443+d1170cfc7",
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
- "gitHead": "b483af77f02d1258c8dad156e097b94f83671d8e"
32
+ "devDependencies": {
33
+ "@atlaspack/core": "2.12.1-dev.3443+d1170cfc7"
34
+ },
35
+ "gitHead": "d1170cfc79beb290b2a066f472f68f71f7d7cb23"
30
36
  }
@@ -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 default (new Transformer({
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
- return {
22
- type: 'posthtml',
23
- version: '0.4.1',
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
- }): Transformer);
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
+ });