diff --git a/.travis.yml b/.travis.yml index d84955b..ee6d51f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,7 @@ language: node_js node_js: - stable - lts/* - - 6 - - 4 + - 10 after_success: - cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js" diff --git a/README.md b/README.md index b0378aa..a5d7005 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,11 @@ module: { |:--:|:--:|:-----:|:----------| |**[`config`](#config)**|`{Object}`|`undefined`|PostHTML Config| |**[`parser`](#parser)**|`{String/Function}`|`undefined`|PostHTML Parser| +|**[`skipParse`](#skipParse)**|`{Boolean}`|`false`|PostHTML Options SkipParse| +|**[`render`](#render)**|`{String/Function}`|`undefined`|PostHTML Render| |**[`plugins`](#plugins)**|`{Array/Function}`|`[]`|PostHTML Plugins| +|**[`sync`](#sync)**|`{boolean}`|`false`|PostHTML Options Sync| +|**[`directives`](#directives)**|`{Array}`|`[]`|PostHTML Options custom [Directives](https://github.com/posthtml/posthtml-parser#directives)| ### `Config` @@ -66,6 +70,7 @@ module: { |**[`path`](#path)**|`{String}`|`loader.resourcePath`|PostHTML Config Path| |**[`ctx`](#context)**|`{Object}`|`{}`|PostHTML Config Context| + If you want to use are shareable config file instead of inline options in your `webpack.config.js` create a `posthtml.config.js` file and place it somewhere down the file tree in your project. The nearest config relative to `dirname(file)` currently processed by the loader applies. This enables **Config Cascading**. Despite some edge cases the config file will be loaded automatically and **no** additional setup is required. If you don't intend to use Config Cascading, it's recommended to place `posthtml.config.js` in the **root** `./` of your project ``` @@ -157,6 +162,50 @@ If you want to use a custom parser e.g [SugarML](https://github.com/posthtml/sug } ``` +### `skipParse` + +If you want to use disable parsing, you can pass it in under the `skipParse` key in the loader options + +#### `{Boolean}` + +**webpack.config.js** +```js +{ + loader: 'posthtml-loader', + options: { + skipParse: false + } +} +``` + +### `Render` + +If you want to use a custom render, you can pass it in under the `render` key in the loader options + +#### `{String}` + +**webpack.config.js** +```js +{ + loader: 'posthtml-loader', + options: { + render: 'posthtml-you-render' + } +} +``` + +#### `{Function}` + +**webpack.config.js** +```js +{ + loader: 'posthtml-loader', + options: { + parser: require('posthtml-you-render')() + } +} +``` + ### `Plugins` Plugins are specified under the `plugins` key in the loader options @@ -191,6 +240,38 @@ Plugins are specified under the `plugins` key in the loader options } ``` +### `Sync` + +Enables sync mode, plugins will run synchronously, throws an error when used with async plugins + +#### `{Boolean}` + +**webpack.config.js** +```js +{ + loader: 'posthtml-loader', + options: { + sync: true + } +} +``` + +### `Directives` + +If you want to use a custom directives, you can pass it in under the `directives` key in the loader options + +#### `{Array}` + +**webpack.config.js** +```js +{ + loader: 'posthtml-loader', + options: { + directives: [{name: '?php', start: '<', end: '>'}] + } +} +``` +

Maintainer

@@ -202,15 +283,6 @@ Plugins are specified under the `plugins` key in the loader options
Michael Ciniawsky - - -
- -

Contributors

- - - -

diff --git a/lib/index.js b/lib/index.js index 735918b..920ddf9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -106,10 +106,9 @@ module.exports = function loader (html, map, meta) { options.parser = require(options.parser)() } - // TODO(michael-ciniawsky) enable if when custom renderer available - // if (typeof options.render === 'string') { - // options.render = require(options.render)() - // } + if (typeof options.render === 'string') { + options.render = require(options.render)() + } return posthtml(plugins) .process(html, options) diff --git a/lib/options.js b/lib/options.js index addbf22..09da1e7 100644 --- a/lib/options.js +++ b/lib/options.js @@ -1,22 +1,14 @@ 'use strict' module.exports = function parseOptions (params) { - if (typeof params.plugins === 'function') { - params.plugins = params.plugins.call(this, this) - } - - let plugins - - if (typeof params.plugins === 'undefined') plugins = [] - else if (Array.isArray(params.plugins)) plugins = params.plugins - else plugins = [params.plugins] + let { plugins, ...options } = params - const options = {} - - if (typeof params !== 'undefined') { - options.parser = params.parser - // options.render = params.render + if (typeof plugins === 'function') { + plugins = plugins.call(this, this) } - return Promise.resolve({ options: options, plugins: plugins }) + if (typeof plugins === 'undefined') plugins = [] + else if (!Array.isArray(plugins)) plugins = [plugins] + + return Promise.resolve({ options, plugins }) } diff --git a/lib/options.json b/lib/options.json index 314f6dd..7cdfb25 100644 --- a/lib/options.json +++ b/lib/options.json @@ -1,6 +1,29 @@ { "type": "object", "properties": { + "sync": { + "type": "boolean" + }, + "directives": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "start": { + "type": "string" + }, + "end": { + "type": "string" + } + } + } + }, + "skipParse": { + "type": "boolean" + }, "ident": { "type": "string" }, @@ -23,6 +46,13 @@ { "instanceof": "Function" } ] }, + "render": { + "oneOf": [ + { "type": "string" }, + { "type": "object" }, + { "instanceof": "Function" } + ] + }, "plugins": { "oneOf": [ { "type": "array" }, diff --git a/package.json b/package.json index 36315e9..07be986 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "posthtml-loader", "description": "PostHTML for Webpack", - "version": "1.0.2", + "version": "2.0.0", "main": "lib/index.js", "engines": { - "node": ">= 4" + "node": ">= 10" }, "files": [ "lib" @@ -18,20 +18,20 @@ "release": "standard-version" }, "dependencies": { - "loader-utils": "^1.1.0", - "posthtml": "^0.12.0", + "loader-utils": "^2.0.0", + "posthtml": "^0.13.2", "posthtml-load-config": "^1.0.0", "schema-utils": "^2.5.0" }, "devDependencies": { "coveralls": "^3.0.7", "del": "^5.1.0", - "jest": "^24.9.0", - "jsdoc-to-markdown": "^5.0.2", + "jest": "^26.4.1", + "jsdoc-to-markdown": "^6.0.1", "memory-fs": "^0.5.0", "posthtml-sugarml": "1.0.0-alpha3", "standard": "^14.3.1", - "standard-version": "^7.0.0", + "standard-version": "^9.0.0", "webpack": "^4.41.2" }, "keywords": [ diff --git a/test/__snapshots__/Errors.test.js.snap b/test/__snapshots__/Errors.test.js.snap index 24ed990..c0e5d47 100644 --- a/test/__snapshots__/Errors.test.js.snap +++ b/test/__snapshots__/Errors.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Errors Validation Error 1`] = ` -"Invalid options object. PostHTML Loader has been initialised using an options object that does not match the API schema. +"Invalid options object. PostHTML Loader has been initialized using an options object that does not match the API schema. - options.plugins should be one of these: [any, ...] | object { … } | function Details: diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap new file mode 100644 index 0000000..1421543 --- /dev/null +++ b/test/__snapshots__/loader.test.js.snap @@ -0,0 +1,6 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Loader Defaults 1`] = ` +"export default \`
Hello
+\`" +`; diff --git a/test/fixtures/options/directives/fixture.html b/test/fixtures/options/directives/fixture.html new file mode 100644 index 0000000..05402e3 --- /dev/null +++ b/test/fixtures/options/directives/fixture.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/fixtures/options/directives/fixture.js b/test/fixtures/options/directives/fixture.js new file mode 100644 index 0000000..310cfd2 --- /dev/null +++ b/test/fixtures/options/directives/fixture.js @@ -0,0 +1 @@ +import html from './fixture.html' // eslint-disable-line diff --git a/test/fixtures/options/render/fixture.html b/test/fixtures/options/render/fixture.html new file mode 100644 index 0000000..5782fa3 --- /dev/null +++ b/test/fixtures/options/render/fixture.html @@ -0,0 +1 @@ +Hello \ No newline at end of file diff --git a/test/fixtures/options/render/fixture.js b/test/fixtures/options/render/fixture.js new file mode 100644 index 0000000..310cfd2 --- /dev/null +++ b/test/fixtures/options/render/fixture.js @@ -0,0 +1 @@ +import html from './fixture.html' // eslint-disable-line diff --git a/test/helpers/compiler.js b/test/helpers/compiler.js index 93cce61..6ee2db7 100644 --- a/test/helpers/compiler.js +++ b/test/helpers/compiler.js @@ -46,6 +46,7 @@ const output = (config) => { module.exports = function (fixture, config, options) { config = { + mode: 'development', devtool: config.devtool || 'sourcemap', context: path.resolve(__dirname, '..', 'fixtures'), entry: `./${fixture}`, diff --git a/test/loader.test.js b/test/loader.test.js index ff14a9f..1603e1e 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -13,7 +13,7 @@ describe('Loader', () => { return webpack('fixture.js', config) .then((stats) => { - const module = stats.toJson().modules[1] + const [module] = stats.toJson().modules expect(module.source).toMatchSnapshot() }) diff --git a/test/options/__snapshots__/config.test.js.snap b/test/options/__snapshots__/config.test.js.snap new file mode 100644 index 0000000..b721f8a --- /dev/null +++ b/test/options/__snapshots__/config.test.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Options config ctx - {Object} 1`] = ` +"export default \`
Hello
+\`" +`; + +exports[`Options config path - {String} 1`] = ` +"export default \`
Hello
+\`" +`; diff --git a/test/options/__snapshots__/directives.test.js.snap b/test/options/__snapshots__/directives.test.js.snap new file mode 100644 index 0000000..28578a0 --- /dev/null +++ b/test/options/__snapshots__/directives.test.js.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Options directives {Array} 1`] = `"export default \`\`"`; diff --git a/test/options/__snapshots__/parser.test.js.snap b/test/options/__snapshots__/parser.test.js.snap new file mode 100644 index 0000000..b106d4d --- /dev/null +++ b/test/options/__snapshots__/parser.test.js.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Options parser {Object} 1`] = `"export default \`
Hello
\`"`; + +exports[`Options parser {String} 1`] = `"export default \`
Hello
\`"`; diff --git a/test/options/__snapshots__/plugins.test.js.snap b/test/options/__snapshots__/plugins.test.js.snap new file mode 100644 index 0000000..3ad6b08 --- /dev/null +++ b/test/options/__snapshots__/plugins.test.js.snap @@ -0,0 +1,16 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Options plugins {Array} 1`] = ` +"export default \`
Hello
+\`" +`; + +exports[`Options plugins {Function} - {Array} 1`] = ` +"export default \`
Hello
+\`" +`; + +exports[`Options plugins {Function} - {Object} 1`] = ` +"export default \`
Hello
+\`" +`; diff --git a/test/options/__snapshots__/render.test.js.snap b/test/options/__snapshots__/render.test.js.snap new file mode 100644 index 0000000..a943fdf --- /dev/null +++ b/test/options/__snapshots__/render.test.js.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Options render {Object} 1`] = `"export default \`Hello\`"`; + +exports[`Options render {String} 1`] = `"export default \`Hello\`"`; diff --git a/test/options/config.test.js b/test/options/config.test.js index 5aecd0d..906d5df 100644 --- a/test/options/config.test.js +++ b/test/options/config.test.js @@ -18,7 +18,7 @@ describe('Options', () => { return webpack('fixture.js', config) .then((stats) => { - const module = stats.toJson().modules[1] + const [module] = stats.toJson().modules expect(module.source).toMatchSnapshot() }) @@ -40,7 +40,7 @@ describe('Options', () => { return webpack('fixture.js', config) .then((stats) => { - const module = stats.toJson().modules[1] + const [module] = stats.toJson().modules expect(module.source).toMatchSnapshot() }) diff --git a/test/options/directives.test.js b/test/options/directives.test.js new file mode 100644 index 0000000..3a10999 --- /dev/null +++ b/test/options/directives.test.js @@ -0,0 +1,30 @@ +'use strict' + +const webpack = require('../helpers/compiler') + +describe('Options', () => { + describe('directives', () => { + test('{Array}', () => { + const config = { + loader: { + test: /\.html$/, + options: { + directives: [{ + name: '?php', + start: '<', + end: '>' + }] + } + } + } + + return webpack('options/directives/fixture.js', config) + .then((stats) => { + const [module] = stats.toJson().modules + + expect(module.source).toMatchSnapshot() + }) + .catch((err) => err) + }) + }) +}) diff --git a/test/options/plugins.test.js b/test/options/plugins.test.js index 36023e7..7784bc6 100644 --- a/test/options/plugins.test.js +++ b/test/options/plugins.test.js @@ -19,7 +19,7 @@ describe('Options', () => { return webpack('fixture.js', config) .then((stats) => { - const module = stats.toJson().modules[1] + const [module] = stats.toJson().modules expect(module.source).toMatchSnapshot() }) @@ -43,7 +43,7 @@ describe('Options', () => { return webpack('fixture.js', config) .then((stats) => { - const module = stats.toJson().modules[1] + const [module] = stats.toJson().modules expect(module.source).toMatchSnapshot() }) @@ -65,7 +65,7 @@ describe('Options', () => { return webpack('fixture.js', config) .then((stats) => { - const module = stats.toJson().modules[1] + const [module] = stats.toJson().modules expect(module.source).toMatchSnapshot() }) diff --git a/test/options/render.test.js b/test/options/render.test.js new file mode 100644 index 0000000..68091fd --- /dev/null +++ b/test/options/render.test.js @@ -0,0 +1,45 @@ +'use strict' + +const webpack = require('../helpers/compiler') + +describe('Options', () => { + describe('render', () => { + test('{String}', () => { + const config = { + loader: { + test: /\.html$/, + options: { + render: 'posthtml-render' + } + } + } + + return webpack('options/render/fixture.js', config) + .then((stats) => { + const [module] = stats.toJson().modules + + expect(module.source).toMatchSnapshot() + }) + .catch((err) => err) + }) + + test('{Object}', () => { + const config = { + loader: { + test: /\.html$/, + options: { + parser: require('posthtml-render') + } + } + } + + return webpack('options/render/fixture.js', config) + .then((stats) => { + const [module] = stats.toJson().modules + + expect(module.source).toMatchSnapshot() + }) + .catch((err) => err) + }) + }) +})