UNPKG

rollup-plugin-stimulus

Version:

Rollup.js plugin for rolling Stimulus.js applications

186 lines (153 loc) 4.76 kB
'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var util = require('util'); var fs = _interopDefault(require('fs')); function processBasePath(moduleConfig, rollupOptions) { if (moduleConfig.rawBasePath) { return moduleConfig.rawBasePath; } let basePath = moduleConfig.basePath; if (!basePath) { basePath = rollupOptions.input.replace(/\/+$/, ''); const baseNamePosition = basePath.lastIndexOf('/'); if (baseNamePosition !== -1) { basePath = basePath.substring(0, baseNamePosition) + '/controllers'; } } if (!basePath.startsWith('/') && !basePath.startsWith('./')) { basePath = `./${basePath.replace(/\/+$/, '')}`; } return basePath; } class Config { constructor() { this.importName = '\0stimulus-controllers'; this.basePath = null; } configure(moduleConfig, rollupOptions) { if (!moduleConfig) { moduleConfig = {}; } else if (typeof moduleConfig === 'string') { moduleConfig = { basePath: moduleConfig }; } this.basePath = processBasePath(moduleConfig, rollupOptions); if (moduleConfig.importName) { this.importName = `\0${moduleConfig.importName}`; } if (!moduleConfig.showWarnings) { const originalWarnHandler = rollupOptions.onwarn; rollupOptions.onwarn = function(warning, warn) { if (warning.code === 'THIS_IS_UNDEFINED' && warning.loc.file.includes('/@stimulus/') ) { return; } if (originalWarnHandler) { originalWarnHandler(warning, warn); } else { warn(warning); } }; } } } /** * @param {string} basePath: the path to search for controllers in * @param {string} path: the path relative to the basePath to search */ function * iterateControllerFilesRecursive(basePath, path) { const dir = path ? `${basePath}/${path}` : basePath; if (!fs.existsSync(dir) || !fs.lstatSync(dir).isDirectory()) { return; } const files = fs.readdirSync(dir, {withFileTypes: true}); for (let file of files) { const relativePath = path ? `${path}/${file.name}` : file.name; if (file.isDirectory()) { yield * iterateControllerFilesRecursive(basePath, relativePath); continue; } if (!file.isFile()) { continue; } const logicalName = (relativePath.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/) || [])[1]; if (logicalName) { const identifier = logicalName.replace(/_/g, '-').replace(/\//g, '--'); yield new Controller(identifier, `${basePath}/${relativePath}`); } }} class Controller { /** * @param {string} basePath: the path to search for controllers in * @returns Controller */ static * findAllInDirectory(basePath) { yield * iterateControllerFilesRecursive(basePath, ''); } constructor(identifier, path) { /** * The controller identifier to be used in the data-controller attribute, * generated using Stimulus' conventions * * @type {string} */ this.identifier = identifier; /** * The path to the file containing the Controller's source, which should * export the Stimulus Controller as its default: `export default class` * * @type {string} */ this.path = path; /** * The controller identifier converted to a format that is safe to use as a * JavaScript variable in the `import` statement. * * @type {string} */ this.importIdentifier = 'import_' + this.identifier.replace(/-/g, '_'); } } function generateImport({importIdentifier: ctrl, path}) { return util.format('import %s from %j;\n', ctrl, path); } function generateExport({identifier: id, importIdentifier: ctrl}) { return util.format(' {identifier: %j, controllerConstructor: %s},\n', id, ctrl); } function generateControllersImport(config) { const controllers = Controller.findAllInDirectory(config.basePath); let imports = ''; let exports = '\nexport default [\n'; for (const controller of controllers) { imports += generateImport(controller); exports += generateExport(controller); } exports += '];\n'; return imports + exports; } function rollupPluginStimulus(moduleConfig) { let config = new Config(); return { name: "rollup-plugin-stimulus", options(options) { config.configure(moduleConfig, options); }, resolveId(id) { if (`\0${id}` === config.importName) { return config.importName; } return null; }, load(id) { if (id !== config.importName) { return; } return generateControllersImport(config); } }; } module.exports = rollupPluginStimulus;