UNPKG

@enact/dev-utils

Version:

A collection of development utilities for Enact apps.

107 lines (96 loc) 3.74 kB
const path = require('path'); const DelegatedSourceDependency = require('webpack/lib/dependencies/DelegatedSourceDependency'); const DelegatedModule = require('webpack/lib/DelegatedModule'); const ExternalsPlugin = require('webpack/lib/ExternalsPlugin'); // Custom DelegateFactoryPlugin designed to redirect Enact framework require() calls // to the external framework function DelegatedEnactFactoryPlugin(options) { this.options = options || {}; } DelegatedEnactFactoryPlugin.prototype.apply = function(normalModuleFactory) { const name = this.options.name; const libReg = new RegExp('^(' + this.options.libraries.join('|') + ')(?=[\\\\\\/]|$)'); normalModuleFactory.plugin('factory', factory => { return function(data, callback) { const request = data.request; if (request && libReg.test(request)) { return callback(null, new DelegatedModule(name, {id: request}, 'require', request)); } return factory(data, callback); }; }); }; // Form a correct filepath that can be used within the build's output directory function normalizePath(dir, file, compiler) { if (path.isAbsolute(dir)) { return path.join(dir, file); } else { return path.relative(path.resolve(compiler.options.output.path), path.join(process.cwd(), dir, file)); } } // Determine if it's a NodeJS output filesystem or if it's a foreign/virtual one. function isNodeOutputFS(compiler) { return ( compiler.outputFileSystem && compiler.outputFileSystem.constructor && compiler.outputFileSystem.constructor.name === 'NodeOutputFileSystem' ); } // Reference plugin to handle rewiring the external Enact framework requests function EnactFrameworkRefPlugin(opts) { this.options = opts || {}; this.options.name = this.options.name || 'enact_framework'; this.options.libraries = this.options.libraries || ['@enact', 'react', 'react-dom']; this.options.external = this.options.external || {}; this.options.external.publicPath = this.options.external.publicPath || this.options.external.path; if (!process.env.ILIB_BASE_PATH) { process.env.ILIB_BASE_PATH = path.join( this.options.external.publicPath, 'node_module', '@enact', 'i18n', 'ilib' ); } } module.exports = EnactFrameworkRefPlugin; EnactFrameworkRefPlugin.prototype.apply = function(compiler) { const name = this.options.name; const libs = this.options.libraries; const external = this.options.external; // Declare enact_framework as an external dependency const externals = {}; externals[name] = name; compiler.apply(new ExternalsPlugin(compiler.options.output.libraryTarget || 'var', externals)); compiler.plugin('compilation', (compilation, params) => { const normalModuleFactory = params.normalModuleFactory; compilation.dependencyFactories.set(DelegatedSourceDependency, normalModuleFactory); compilation.plugin('html-webpack-plugin-alter-chunks', chunks => { const chunkFiles = [normalizePath(external.publicPath, 'enact.css', compiler)]; if (!external.snapshot) { chunkFiles.unshift(normalizePath(external.publicPath, 'enact.js', compiler)); } // Add the framework files as a pseudo-chunk so they get injected into the HTML chunks.unshift({ names: ['enact_framework'], files: chunkFiles }); return chunks; }); if (external.snapshot && isNodeOutputFS(compiler)) { compilation.plugin('webos-meta-root-appinfo', meta => { meta.v8SnapshotFile = normalizePath(external.publicPath, 'snapshot_blob.bin', compiler); return meta; }); } }); // Apply the Enact factory plugin to handle the require() delagation/rerouting compiler.plugin('compile', params => { params.normalModuleFactory.apply( new DelegatedEnactFactoryPlugin({ name: name, libraries: libs }) ); }); };