Skip to content

Commit

Permalink
Check rollup types, add jsdoc-plugin-typescript
Browse files Browse the repository at this point in the history
I began to add a larger test using Vite and this plugin, and the
HandlebarsPrecompiler() function produced type check errors. So it
seemed prudent to actually use Rollup types instead of simulating them
and instructing users to disable checking.

At the same time, I learned I didn't need to disable type checking for
my vitest.config.js files after all.

Some of the specific changes include:

- Using `...(configDefaults.coverage.exclude || [])` as appropriate to
  avoid type errors due to configDefaults.coverage.exclude potentially
  being undefined.

- Adding 'rollup' as a devDependency and adding `import("rollup").Type`
  as appropriate in JSDoc `@type` directives.

- Adding 'jsdoc-plugin-typescript' to the build to handle the TypeScript
  `import().Type` directives. This ended up pulling in the 'es-abstract'
  module, which blew up the pnpm-lock.yaml file. If I get an itch, I'll
  implement my own plugin one day and replace it.

- Removing redundant types from lib/types.js. This included removing
  PrecompilerOptions, which I realized I was already visible from the
  'handlebars' module.

- Adding "DOM" to the "lib" field of jsconfig.json.

- Added a JSDoc type cast to main.test.js to eliminate type errors.
  This is safe because we're testing our own object that is known to
  have certain methods defined.
  • Loading branch information
mbland committed Jan 11, 2024
1 parent 82145e2 commit 8b36b2a
Show file tree
Hide file tree
Showing 10 changed files with 575 additions and 90 deletions.
26 changes: 13 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,27 @@

import PluginImpl, { PLUGIN_NAME } from './lib/index.js'
// eslint-disable-next-line no-unused-vars
import { PluginOptions, Transform } from './lib/types.js'
import { PluginOptions } from './lib/types.js'

/**
* A Rollup plugin object for precompiling Handlebars templates.
* @module rollup-plugin-handlebars-precompiler
*/

/**
* @typedef {object} RollupPlugin
* @property {string} name - plugin name
* @property {Function} resolveId - resolves the plugin's own import ID
* @property {Function} load - emits the plugin's helper module code
* @property {Function} transform - emits JavaScript code compiled from
* Handlebars templates
* @see https://rollupjs.org/plugin-development/
*/

/**
* Returns a Rollup plugin object for precompiling Handlebars templates.
* @function default
* @param {PluginOptions} options - plugin configuration options
* @returns {RollupPlugin} - the configured plugin object
* @returns {import("rollup").Plugin} - the configured plugin object
* @see https://rollupjs.org/plugin-development/
*/
export default function HandlebarsPrecompiler(options) {
const p = new PluginImpl(options)
return {
name: PLUGIN_NAME,

/**
* @type {import("rollup").ResolveIdHook}
* @param {string} id - import identifier to resolve
* @returns {(string | undefined)} - the plugin ID if id matches it
* @see https://rollupjs.org/plugin-development/#resolveid
Expand All @@ -76,6 +68,7 @@ export default function HandlebarsPrecompiler(options) {
},

/**
* @type {import("rollup").LoadHook}
* @param {string} id - import identifier to load
* @returns {(string | undefined)} - the plugin helper module if id matches
* @see https://rollupjs.org/plugin-development/#load
Expand All @@ -84,7 +77,14 @@ export default function HandlebarsPrecompiler(options) {
return p.shouldEmitHelpersModule(id) ? p.helpersModule() : undefined
},

/** @type {Transform} */
/**
* @type {import("rollup").TransformHook}
* @param {string} code - potential Handlebars template to precompile
* @param {string} id - import identifier of possible Handlebars template
* @returns {(Partial<import("rollup").SourceDescription> | undefined)} -
* the precompiled Handlebars template, if id identifies a template file
* @see https://rollupjs.org/plugin-development/#transform
*/
transform: function (code, id) {
return p.isTemplate(id) ? p.compile(code, id) : undefined
}
Expand Down
3 changes: 2 additions & 1 deletion jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"compilerOptions": {
"checkJs": true,
"lib": [
"ES2022"
"ES2022",
"DOM"
],
"module": "node16",
"target": "es2020",
Expand Down
8 changes: 7 additions & 1 deletion jsdoc.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
{
"plugins": [ "plugins/markdown" ],
"plugins": [
"plugins/markdown",
"jsdoc-plugin-typescript"
],
"recurseDepth": 10,
"source": {
"includePattern": ".+\\.js$",
"exclude": ["node_modules"]
},
"typescript": {
"moduleRoot": "."
},
"opts": {
"destination": "jsdoc",
"recurse": true,
Expand Down
26 changes: 20 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@
* obtain one at https://mozilla.org/MPL/2.0/.
*/

/**
* @module rollup-plugin-handlebars-precompiler/lib
*/

import collectPartials from './partials.js'
import {
// eslint-disable-next-line no-unused-vars
Compiled, PartialName, PartialPath, PluginOptions, SourceMap, Transform
} from './types.js'
// eslint-disable-next-line no-unused-vars
import { PartialName, PartialPath, PluginOptions } from './types.js'
import { createFilter } from '@rollup/pluginutils'
import Handlebars from 'handlebars'

Expand Down Expand Up @@ -78,7 +80,8 @@ const IMPORT_HELPERS = `import Render from '${PLUGIN_ID}'`
* @param {number} numLinesBeforeTmpl - number of empty lines to add to the
* beginning of the source mappings to account for the generated code before
* the precompiled template
* @returns {SourceMap} - potentially modified Handlebars source map
* @returns {import("rollup").SourceMapInput} - potentially modified Handlebars
* source map
*/

/**
Expand Down Expand Up @@ -156,7 +159,18 @@ export default class PluginImpl {
*/
isTemplate(id) { return this.#isTemplate(id) }

/** @type {Transform} */
/**
* @typedef {object} Compiled
* @property {string} code - the precompiled Handlebars template code
* @property {string} map - the Handlebars source map as a JSON string
*/

/**
* @param {string} code - Handlebars template source to precompile
* @param {string} id - file path used to import the Handlebars template
* @returns {Partial<import("rollup").SourceDescription>} - JavaScript
* precompiled from a Handlebars template
*/
compile(code, id) {
const opts = this.#compilerOpts(id)
const ast = Handlebars.parse(code, opts)
Expand Down
4 changes: 4 additions & 0 deletions lib/partials.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
* obtain one at https://mozilla.org/MPL/2.0/.
*/

/**
* @module rollup-plugin-handlebars-precompiler/partials
*/

import Handlebars from 'handlebars'

/**
Expand Down
54 changes: 7 additions & 47 deletions lib/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
* obtain one at https://mozilla.org/MPL/2.0/.
*/

/**
* @module rollup-plugin-handlebars-precompiler/types
*/

/**
* @callback PartialName
* @param {string} id - import identifier of a Handlebars partial template
Expand All @@ -53,16 +57,6 @@ export let PartialName
/** @type {PartialPath} */
export let PartialPath

/**
* An approximation of Handlebars's PrecompileOptions
* @typedef {object} PrecompileOptions
* @property {string} [srcName] - input file path used to generate source map;
* should not be set, and will be deleted if present
* @property {string} [destName] - destination file path used to generate source
* map; should not be set, and will be deleted if present
* @see https://handlebarsjs.com/api-reference/compilation.html
*/

/**
* @typedef {object} PluginOptions
* @property {string[]} [helpers] - an array of file paths to modules containing
Expand All @@ -77,45 +71,11 @@ export let PartialPath
* name into the name used to apply the partial in other templates
* @property {PartialPath} [partialPath] - function to transform a partial's
* name and that of the module importing it into its import path
* @property {PrecompileOptions} [compiler] - compiler options passed through to
* Handlebars.parse() and Handlebars.precompile()
* @property {PrecompileOptions} [compiler] - Handlebars compiler options passed
* through to Handlebars.parse() and Handlebars.precompile()
* @property {boolean} [sourcemap] - disables source map generation when false
* @property {boolean} [sourceMap] - disables source map generation when false
* @see https://handlebarsjs.com/api-reference/compilation.html
*/
/** @type {PluginOptions} */
export let PluginOptions

/**
* @typedef {object} Compiled
* @property {string} code - the precompiled Handlebars template code
* @property {string} map - the Handlebars source map as a JSON string
*/
/** @type {Compiled} */
export let Compiled

/**
* @typedef {object} SourceMap - a source map for transformed source code
* @property {string} mappings - encoded mapping data
* @see https://sourcemaps.info/spec.html
*/
/** @type {SourceMap} */
export let SourceMap

/**
* @typedef {object} TransformResult - result from RollupPlugin.transform()
* @property {string} code - the transformed source code
* @property {SourceMap} map - the source map for the transformed source code
*/
/** @type {TransformResult} */
export let TransformResult

/**
* @callback Transform
* @param {string} code - source code to potentially transform
* @param {string} id - import ID of source file
* @returns {(TransformResult | undefined)} - JavaScript precompiled from a
* Handlebars template, if id matches the configured template filter
* @see https://rollupjs.org/plugin-development/#transform
*/
/** @type {Transform} */
export let Transform
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
"eslint-plugin-vitest": "^0.3.20",
"jsdoc": "^4.0.2",
"jsdoc-cli-wrapper": "^1.0.4",
"jsdoc-plugin-typescript": "^2.2.1",
"rollup": "^4.9.4",
"typescript": "^5.3.3",
"vitest": "^1.1.3"
},
Expand Down
Loading

0 comments on commit 8b36b2a

Please sign in to comment.