@parcel/transformer-posthtml 2.0.0-nightly.97 → 2.1.0

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.
@@ -5,42 +5,147 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _plugin = require("@parcel/plugin");
8
+ function _plugin() {
9
+ const data = require("@parcel/plugin");
9
10
 
10
- var _posthtml = _interopRequireDefault(require("posthtml"));
11
+ _plugin = function () {
12
+ return data;
13
+ };
11
14
 
12
- var _posthtmlParser = _interopRequireDefault(require("posthtml-parser"));
15
+ return data;
16
+ }
13
17
 
14
- var _posthtmlRender = _interopRequireDefault(require("posthtml-render"));
18
+ function _path() {
19
+ const data = _interopRequireDefault(require("path"));
15
20
 
16
- var _nullthrows = _interopRequireDefault(require("nullthrows"));
21
+ _path = function () {
22
+ return data;
23
+ };
17
24
 
18
- var _semver = _interopRequireDefault(require("semver"));
25
+ return data;
26
+ }
27
+
28
+ function _posthtml() {
29
+ const data = _interopRequireDefault(require("posthtml"));
30
+
31
+ _posthtml = function () {
32
+ return data;
33
+ };
34
+
35
+ return data;
36
+ }
37
+
38
+ function _posthtmlParser() {
39
+ const data = require("posthtml-parser");
40
+
41
+ _posthtmlParser = function () {
42
+ return data;
43
+ };
44
+
45
+ return data;
46
+ }
47
+
48
+ function _posthtmlRender() {
49
+ const data = require("posthtml-render");
50
+
51
+ _posthtmlRender = function () {
52
+ return data;
53
+ };
54
+
55
+ return data;
56
+ }
57
+
58
+ function _nullthrows() {
59
+ const data = _interopRequireDefault(require("nullthrows"));
60
+
61
+ _nullthrows = function () {
62
+ return data;
63
+ };
64
+
65
+ return data;
66
+ }
67
+
68
+ function _semver() {
69
+ const data = _interopRequireDefault(require("semver"));
70
+
71
+ _semver = function () {
72
+ return data;
73
+ };
74
+
75
+ return data;
76
+ }
77
+
78
+ function _utils() {
79
+ const data = require("@parcel/utils");
80
+
81
+ _utils = function () {
82
+ return data;
83
+ };
84
+
85
+ return data;
86
+ }
19
87
 
20
88
  var _loadPlugins = _interopRequireDefault(require("./loadPlugins"));
21
89
 
22
90
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
91
 
24
- var _default = new _plugin.Transformer({
25
- async getConfig({
26
- asset,
27
- options
92
+ var _default = new (_plugin().Transformer)({
93
+ async loadConfig({
94
+ config,
95
+ options,
96
+ logger
28
97
  }) {
29
- let config = await asset.getConfig(['.posthtmlrc', '.posthtmlrc.js', 'posthtml.config.js'], {
98
+ if (!config.isSource) {
99
+ return;
100
+ }
101
+
102
+ let configFile = await config.getConfig(['.posthtmlrc', '.posthtmlrc.js', 'posthtml.config.js'], {
30
103
  packageKey: 'posthtml'
31
104
  });
32
- config = config || {}; // load plugins
33
105
 
34
- config.plugins = await (0, _loadPlugins.default)(config.plugins, asset.filePath, options); // tells posthtml that we have already called parse
106
+ if (configFile) {
107
+ let isJavascript = _path().default.extname(configFile.filePath) === '.js';
108
+
109
+ if (isJavascript) {
110
+ // We have to invalidate on startup in case the config is non-deterministic,
111
+ // e.g. using unknown environment variables, reading from the filesystem, etc.
112
+ logger.warn({
113
+ message: 'WARNING: Using a JavaScript PostHTML config file means losing out on caching features of Parcel. Use a .posthtmlrc (JSON) file whenever possible.'
114
+ });
115
+ config.invalidateOnStartup(); // Also add the config as a dev dependency so we attempt to reload in watch mode.
116
+
117
+ config.addDevDependency({
118
+ specifier: (0, _utils().relativePath)(_path().default.dirname(config.searchPath), configFile.filePath),
119
+ resolveFrom: config.searchPath
120
+ });
121
+ } // Load plugins. This must be done before adding dev dependencies so we auto install.
122
+
123
+
124
+ let plugins = await (0, _loadPlugins.default)(configFile.contents.plugins, config.searchPath, options); // Now add dev dependencies so we invalidate when they change.
125
+
126
+ let pluginArray = Array.isArray(configFile.contents.plugins) ? configFile.contents.plugins : Object.keys(configFile.contents.plugins);
127
+
128
+ for (let p of pluginArray) {
129
+ if (typeof p === 'string') {
130
+ config.addDevDependency({
131
+ specifier: p,
132
+ resolveFrom: configFile.filePath
133
+ });
134
+ }
135
+ }
35
136
 
36
- config.skipParse = true;
37
- return config;
137
+ configFile.contents.plugins = plugins; // tells posthtml that we have already called parse
138
+
139
+ configFile.contents.skipParse = true;
140
+ delete configFile.contents.render;
141
+ return configFile.contents;
142
+ }
38
143
  },
39
144
 
40
145
  canReuseAST({
41
146
  ast
42
147
  }) {
43
- return ast.type === 'posthtml' && _semver.default.satisfies(ast.version, '^0.4.0');
148
+ return ast.type === 'posthtml' && _semver().default.satisfies(ast.version, '^0.4.0');
44
149
  },
45
150
 
46
151
  async parse({
@@ -55,8 +160,10 @@ var _default = new _plugin.Transformer({
55
160
  return {
56
161
  type: 'posthtml',
57
162
  version: '0.4.1',
58
- program: (0, _posthtmlParser.default)((await asset.getCode()), {
59
- lowerCaseAttributeNames: true
163
+ program: (0, _posthtmlParser().parser)(await asset.getCode(), {
164
+ lowerCaseAttributeNames: true,
165
+ sourceLocations: true,
166
+ xmlMode: asset.type === 'xhtml'
60
167
  })
61
168
  };
62
169
  },
@@ -69,8 +176,10 @@ var _default = new _plugin.Transformer({
69
176
  return [asset];
70
177
  }
71
178
 
72
- const ast = (0, _nullthrows.default)(asset.ast);
73
- let res = await (0, _posthtml.default)(config.plugins).process(ast.program, config);
179
+ let ast = (0, _nullthrows().default)(await asset.getAST());
180
+ let res = await (0, _posthtml().default)(config.plugins).process(ast.program, { ...config,
181
+ plugins: config.plugins
182
+ });
74
183
 
75
184
  if (res.messages) {
76
185
  await Promise.all(res.messages.map(({
@@ -78,25 +187,30 @@ var _default = new _plugin.Transformer({
78
187
  file: filePath
79
188
  }) => {
80
189
  if (type === 'dependency') {
81
- return asset.addIncludedFile({
82
- filePath
83
- });
190
+ return asset.invalidateOnFileChange(filePath);
84
191
  }
85
192
 
86
193
  return Promise.resolve();
87
194
  }));
88
195
  }
89
196
 
90
- ast.program = res.tree;
91
- asset.ast = ast;
197
+ asset.setAST({
198
+ type: 'posthtml',
199
+ version: '0.4.1',
200
+ program: JSON.parse(JSON.stringify(res.tree)) // posthtml adds functions to the AST that are not serializable
201
+
202
+ });
92
203
  return [asset];
93
204
  },
94
205
 
95
206
  generate({
207
+ ast,
96
208
  asset
97
209
  }) {
98
210
  return {
99
- code: (0, _posthtmlRender.default)((0, _nullthrows.default)(asset.ast).program)
211
+ content: (0, _posthtmlRender().render)(ast.program, {
212
+ closingSingleTag: asset.type === 'xhtml' ? 'slash' : undefined
213
+ })
100
214
  };
101
215
  }
102
216
 
@@ -7,26 +7,23 @@ exports.default = loadExternalPlugins;
7
7
 
8
8
  async function loadExternalPlugins(plugins, relative, options) {
9
9
  if (Array.isArray(plugins)) {
10
- return Promise.all(plugins.map(p => loadPlugin(p, relative, null, options.packageManager)).filter(Boolean));
10
+ return Promise.all(plugins.map(p => loadPlugin(p, relative, null, options.packageManager, options.shouldAutoInstall)).filter(Boolean));
11
11
  } else if (typeof plugins === 'object') {
12
- let mapPlugins = await Promise.all(Object.keys(plugins).map(p => loadPlugin(p, relative, plugins[p], options.packageManager)));
12
+ let mapPlugins = await Promise.all(Object.keys(plugins).map(p => loadPlugin(p, relative, plugins[p], options.packageManager, options.shouldAutoInstall)));
13
13
  return mapPlugins.filter(Boolean);
14
14
  } else {
15
15
  return [];
16
16
  }
17
17
  }
18
18
 
19
- async function loadPlugin(pluginArg, relative, options = {}, packageManager) {
19
+ async function loadPlugin(pluginArg, relative, options = {}, packageManager, shouldAutoInstall) {
20
20
  if (typeof pluginArg !== 'string') {
21
21
  return pluginArg;
22
22
  }
23
23
 
24
- let plugin = await packageManager.require(pluginArg, relative);
24
+ let plugin = await packageManager.require(pluginArg, relative, {
25
+ shouldAutoInstall
26
+ });
25
27
  plugin = plugin.default || plugin;
26
-
27
- if (options != null && typeof options === 'object' && Object.keys(options).length > 0) {
28
- plugin = plugin(options);
29
- }
30
-
31
- return plugin.default || plugin;
28
+ return plugin(options);
32
29
  }
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@parcel/transformer-posthtml",
3
- "version": "2.0.0-nightly.97+a63f3fc9",
3
+ "version": "2.1.0",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
+ "funding": {
9
+ "type": "opencollective",
10
+ "url": "https://opencollective.com/parcel"
11
+ },
8
12
  "repository": {
9
13
  "type": "git",
10
14
  "url": "https://github.com/parcel-bundler/parcel.git"
@@ -12,15 +16,17 @@
12
16
  "main": "lib/PostHTMLTransformer.js",
13
17
  "source": "src/PostHTMLTransformer.js",
14
18
  "engines": {
15
- "parcel": "^2.0.0-alpha.1.1"
19
+ "node": ">= 12.0.0",
20
+ "parcel": "^2.1.0"
16
21
  },
17
22
  "dependencies": {
18
- "@parcel/plugin": "2.0.0-nightly.97+a63f3fc9",
23
+ "@parcel/plugin": "^2.1.0",
24
+ "@parcel/utils": "^2.1.0",
19
25
  "nullthrows": "^1.1.1",
20
- "posthtml": "^0.11.3",
21
- "posthtml-parser": "^0.4.1",
22
- "posthtml-render": "^1.1.5",
23
- "semver": "^5.4.1"
26
+ "posthtml": "^0.16.5",
27
+ "posthtml-parser": "^0.10.1",
28
+ "posthtml-render": "^3.0.0",
29
+ "semver": "^5.7.1"
24
30
  },
25
- "gitHead": "a63f3fc9726483219412920faeb255e035f90747"
31
+ "gitHead": "5a80fbe4af8797d0aab248a66f5254f42f00e83e"
26
32
  }
@@ -2,30 +2,78 @@
2
2
 
3
3
  import {Transformer} from '@parcel/plugin';
4
4
 
5
+ import path from 'path';
5
6
  import posthtml from 'posthtml';
6
- import parse from 'posthtml-parser';
7
- import render from 'posthtml-render';
7
+ import {parser as parse} from 'posthtml-parser';
8
+ import {render} from 'posthtml-render';
8
9
  import nullthrows from 'nullthrows';
9
10
  import semver from 'semver';
11
+ import {relativePath} from '@parcel/utils';
10
12
  import loadPlugins from './loadPlugins';
11
13
 
12
- export default new Transformer({
13
- async getConfig({asset, options}) {
14
- let config = await asset.getConfig(
14
+ export default (new Transformer({
15
+ async loadConfig({config, options, logger}) {
16
+ if (!config.isSource) {
17
+ return;
18
+ }
19
+
20
+ let configFile = await config.getConfig(
15
21
  ['.posthtmlrc', '.posthtmlrc.js', 'posthtml.config.js'],
16
22
  {
17
23
  packageKey: 'posthtml',
18
24
  },
19
25
  );
20
26
 
21
- config = config || {};
22
-
23
- // load plugins
24
- config.plugins = await loadPlugins(config.plugins, asset.filePath, options);
27
+ if (configFile) {
28
+ let isJavascript = path.extname(configFile.filePath) === '.js';
29
+ if (isJavascript) {
30
+ // We have to invalidate on startup in case the config is non-deterministic,
31
+ // e.g. using unknown environment variables, reading from the filesystem, etc.
32
+ logger.warn({
33
+ message:
34
+ 'WARNING: Using a JavaScript PostHTML config file means losing out on caching features of Parcel. Use a .posthtmlrc (JSON) file whenever possible.',
35
+ });
36
+
37
+ config.invalidateOnStartup();
38
+
39
+ // Also add the config as a dev dependency so we attempt to reload in watch mode.
40
+ config.addDevDependency({
41
+ specifier: relativePath(
42
+ path.dirname(config.searchPath),
43
+ configFile.filePath,
44
+ ),
45
+ resolveFrom: config.searchPath,
46
+ });
47
+ }
48
+
49
+ // Load plugins. This must be done before adding dev dependencies so we auto install.
50
+ let plugins = await loadPlugins(
51
+ configFile.contents.plugins,
52
+ config.searchPath,
53
+ options,
54
+ );
25
55
 
26
- // tells posthtml that we have already called parse
27
- config.skipParse = true;
28
- return config;
56
+ // Now add dev dependencies so we invalidate when they change.
57
+ let pluginArray = Array.isArray(configFile.contents.plugins)
58
+ ? configFile.contents.plugins
59
+ : Object.keys(configFile.contents.plugins);
60
+ for (let p of pluginArray) {
61
+ if (typeof p === 'string') {
62
+ config.addDevDependency({
63
+ specifier: p,
64
+ resolveFrom: configFile.filePath,
65
+ });
66
+ }
67
+ }
68
+
69
+ configFile.contents.plugins = plugins;
70
+
71
+ // tells posthtml that we have already called parse
72
+ configFile.contents.skipParse = true;
73
+ delete configFile.contents.render;
74
+
75
+ return configFile.contents;
76
+ }
29
77
  },
30
78
 
31
79
  canReuseAST({ast}) {
@@ -43,6 +91,8 @@ export default new Transformer({
43
91
  version: '0.4.1',
44
92
  program: parse(await asset.getCode(), {
45
93
  lowerCaseAttributeNames: true,
94
+ sourceLocations: true,
95
+ xmlMode: asset.type === 'xhtml',
46
96
  }),
47
97
  };
48
98
  },
@@ -52,30 +102,37 @@ export default new Transformer({
52
102
  return [asset];
53
103
  }
54
104
 
55
- const ast = nullthrows(asset.ast);
56
-
57
- let res = await posthtml(config.plugins).process(ast.program, config);
105
+ let ast = nullthrows(await asset.getAST());
106
+ let res = await posthtml(config.plugins).process(ast.program, {
107
+ ...config,
108
+ plugins: config.plugins,
109
+ });
58
110
 
59
111
  if (res.messages) {
60
112
  await Promise.all(
61
113
  res.messages.map(({type, file: filePath}) => {
62
114
  if (type === 'dependency') {
63
- return asset.addIncludedFile({filePath});
115
+ return asset.invalidateOnFileChange(filePath);
64
116
  }
65
117
  return Promise.resolve();
66
118
  }),
67
119
  );
68
120
  }
69
121
 
70
- ast.program = res.tree;
71
- asset.ast = ast;
122
+ asset.setAST({
123
+ type: 'posthtml',
124
+ version: '0.4.1',
125
+ program: JSON.parse(JSON.stringify(res.tree)), // posthtml adds functions to the AST that are not serializable
126
+ });
72
127
 
73
128
  return [asset];
74
129
  },
75
130
 
76
- generate({asset}) {
131
+ generate({ast, asset}) {
77
132
  return {
78
- code: render(nullthrows(asset.ast).program),
133
+ content: render(ast.program, {
134
+ closingSingleTag: asset.type === 'xhtml' ? 'slash' : undefined,
135
+ }),
79
136
  };
80
137
  },
81
- });
138
+ }): Transformer);
@@ -11,14 +11,28 @@ export default async function loadExternalPlugins(
11
11
  if (Array.isArray(plugins)) {
12
12
  return Promise.all(
13
13
  plugins
14
- .map(p => loadPlugin(p, relative, null, options.packageManager))
14
+ .map(p =>
15
+ loadPlugin(
16
+ p,
17
+ relative,
18
+ null,
19
+ options.packageManager,
20
+ options.shouldAutoInstall,
21
+ ),
22
+ )
15
23
  .filter(Boolean),
16
24
  );
17
25
  } else if (typeof plugins === 'object') {
18
26
  let _plugins = plugins;
19
27
  let mapPlugins = await Promise.all(
20
28
  Object.keys(plugins).map(p =>
21
- loadPlugin(p, relative, _plugins[p], options.packageManager),
29
+ loadPlugin(
30
+ p,
31
+ relative,
32
+ _plugins[p],
33
+ options.packageManager,
34
+ options.shouldAutoInstall,
35
+ ),
22
36
  ),
23
37
  );
24
38
  return mapPlugins.filter(Boolean);
@@ -32,21 +46,17 @@ async function loadPlugin(
32
46
  relative: FilePath,
33
47
  options: mixed = {},
34
48
  packageManager: PackageManager,
49
+ shouldAutoInstall: boolean,
35
50
  ): mixed {
36
51
  if (typeof pluginArg !== 'string') {
37
52
  return pluginArg;
38
53
  }
39
54
 
40
- let plugin = await packageManager.require(pluginArg, relative);
41
- plugin = plugin.default || plugin;
55
+ let plugin = await packageManager.require(pluginArg, relative, {
56
+ shouldAutoInstall,
57
+ });
42
58
 
43
- if (
44
- options != null &&
45
- typeof options === 'object' &&
46
- Object.keys(options).length > 0
47
- ) {
48
- plugin = plugin(options);
49
- }
59
+ plugin = plugin.default || plugin;
50
60
 
51
- return plugin.default || plugin;
61
+ return plugin(options);
52
62
  }