UNPKG

@wpk-cli/command-add

Version:
508 lines (417 loc) 14.8 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var babel = _interopRequireWildcard(require("@babel/core")); var _babelPluginDetective = _interopRequireDefault(require("babel-plugin-detective")); var _fs = _interopRequireDefault(require("fs")); var _chalk = _interopRequireDefault(require("chalk")); var _join = _interopRequireDefault(require("lodash/join")); var _isFunction = _interopRequireDefault(require("lodash/isFunction")); var _startsWith = _interopRequireDefault(require("lodash/startsWith")); var _endsWith = _interopRequireDefault(require("lodash/endsWith")); var _isObject = _interopRequireDefault(require("lodash/isObject")); var _some = _interopRequireDefault(require("lodash/some")); var _size = _interopRequireDefault(require("lodash/size")); var _filter = _interopRequireDefault(require("lodash/filter")); var _logger = _interopRequireDefault(require("@wpk-cli/logger")); var _concat = _interopRequireDefault(require("lodash/concat")); var _flatten = _interopRequireDefault(require("lodash/flatten")); var _isArray = _interopRequireDefault(require("lodash/isArray")); var _ora = _interopRequireDefault(require("ora")); var _isString = _interopRequireDefault(require("lodash/isString")); var _isPlainObject = _interopRequireDefault(require("lodash/isPlainObject")); var _map = _interopRequireDefault(require("lodash/map")); var _path = _interopRequireDefault(require("path")); var _castArray = _interopRequireDefault(require("lodash/castArray")); var _prompt = _interopRequireDefault(require("@wpk-cli/prompt")); var _utilities = require("@wpk-cli/utilities"); var _config = require("@wpk-cli/config"); let discoveredVendorModules = []; const help = { /** * $configFilename **/ $configFilename: `\ {yellow About DLL config filename:} A DLL config is a special kind of webpack config that is configured with the \ DllPlugin webpack plugin.\n This option defines the filename of the DLL config. You can also provide an \ absolute or relative path to the location.`, /** * $outputFilename **/ $outputFilename: `\ {yellow About DLL bundle filename:} When the DLL config is run it will produce a DLL bundle, which is referenced by \ configs that use the DLL.\n This option defines the DLL bundle name.`, /** * $path **/ $path: `\ {yellow About Output path:} The location where the DLL bundle should be written. Defaults to the \`output.path\` \ of the webpack config the DLL is being added to, and will rarely need changing.`, /** * $useDiscoveredVendorModules * * We use a function here because it will be invoked just prior to when the question is asked * and so after we have actually resolved the npm modules in use. **/ $useDiscoveredVendorModules: () => `\ {yellow About discovered vendor modules:} wpk has searched the application directory defined by your webpack config to find \ vendor modules that you are likely to want to include in the DLL bundle.\n Select yes to configure the DLL config to bundle these as vendor modules: ${(0, _join.default)(discoveredVendorModules, ", ")}`, /** * $modules **/ $modules: `\ {yellow About other modules:} You can enter the module names that you want includes in the DLL bundle here.\n Enter the modules separated by a comma. For example, to include React and React DOM, \ type {grey "react, react-dom"}.` }; const defaultAnswers = (_, { config }) => ({ $configFilename: "library.webpack.config.js", $outputFilename: "[name].dll.js", $dllPluginName: "[name]", $path: () => { // TODO not working with --yes let outputPath = config.getOption("output.path"); if (outputPath) { outputPath = (0, _castArray.default)(outputPath.value); return (0, _join.default)(outputPath, "/"); } return "dist"; }, $modules: [] }); const questions = (cmd, { config, configPath }) => [{ name: "$configFilename", message: "Config filename:", type: "input", default: defaultAnswers.$configFilename, validate: _prompt.default.validators.fileNotExists(configPath), wpk: { help: help.$configFilename } }, { name: "$outputFilename", message: "Bundle filename", type: "input", default: defaultAnswers.$outputFilename, wpk: { help: help.$outputFilename } }, { name: "$dllPluginName", message: "Plugin name", type: "input", default: defaultAnswers.$dllPluginName, wpk: { help: help.$dllPluginName } }, { name: "$path", message: "Output path:", type: "input", default: defaultAnswers.$path, wpk: { help: help.$path } }, { name: "$useDiscoveredVendorModules", message: "Include discovered vendor modules (see below):", type: "confirm", when: (0, _size.default)(discoveredVendorModules) > 0, wpk: { help: help.$useDiscoveredVendorModules } }, { name: "$modules", message: "Other modules to include:", type: "input", filter: _prompt.default.filters.split(","), default: defaultAnswers.$modules, validate: modules => { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = modules[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { const mod = _step.value; if (/\s+/.test(mod)) { return "Module names cannot contain whitespace"; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return true; }, wpk: { help: help.$modules } }]; function findVendorModules(_x, _x2) { return _findVendorModules.apply(this, arguments); } function _findVendorModules() { _findVendorModules = (0, _asyncToGenerator2.default)(function* (filePath, extensions) { const result = yield babel.transformFileSync(filePath, { plugins: [_babelPluginDetective.default] }); let modules = result.metadata.requires.strings; if (modules.length) { const children = yield Promise.map(modules, module => { if (!(0, _startsWith.default)(module, ".")) { return []; } const dirname = _path.default.dirname(filePath); let modulePath = _path.default.resolve(dirname, module); if (!(0, _some.default)(extensions, e => (0, _endsWith.default)(modulePath, e))) { let extension; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = extensions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { const ext = _step2.value; if (_fs.default.existsSync(modulePath + ext)) { extension = ext; break; } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } if (!extension) { return []; } modulePath = modulePath + extension; } return findVendorModules(modulePath, extensions); }); modules = (0, _concat.default)(modules, (0, _flatten.default)(children)); } return (0, _filter.default)(modules, module => !(0, _startsWith.default)(module, ".")); }); return _findVendorModules.apply(this, arguments); } function processEntries(_x3) { return _processEntries.apply(this, arguments); } function _processEntries() { _processEntries = (0, _asyncToGenerator2.default)(function* (entryPaths) { // TODO derive extensions from config resolve.extensions? const extensions = [".js", ".jsx", ".mjs"]; let modules = []; var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = entryPaths[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { const entryPath = _step3.value; modules = (0, _concat.default)(modules, (yield findVendorModules(entryPath, extensions))); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return != null) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } return modules; }); return _processEntries.apply(this, arguments); } function addDll_runBeforePrompt(_x4, _x5) { return _addDll_runBeforePrompt.apply(this, arguments); } function _addDll_runBeforePrompt() { _addDll_runBeforePrompt = (0, _asyncToGenerator2.default)(function* (cmd, { configPath }) { const spinner = (0, _ora.default)("searching for vendor modules in application").start(); let config = yield global.wpk.try("to load the config", () => require(configPath)); if ((0, _isFunction.default)(config)) { // TODO better support for function configs somehow? config = yield config(); } if (!(0, _isObject.default)(config)) { throw new Error("config does not export an object"); } if ("entry" in config) { try { if ((0, _isPlainObject.default)(config.entry)) { discoveredVendorModules = yield Promise.all((0, _map.default)(config.entry, val => { if ((0, _isArray.default)(val)) { return processEntries(val); } else if ((0, _isString.default)(val)) { return processEntries([val]); } })); } else if ((0, _isArray.default)(config.entry)) { discoveredVendorModules = yield processEntries(config.entry); } else if ((0, _isString.default)(config.entry)) { discoveredVendorModules = yield processEntries([config.entry]); } } catch (err) { spinner.fail(); _logger.default.warn("error processing entry files:", err.message); _logger.default.warn("could not derive vendor modules (see error above)"); if (cmd.wpkDebug) { throw err; } return; } } spinner.succeed(); }); return _addDll_runBeforePrompt.apply(this, arguments); } function addDll_runAfterPrompt(_x6, _x7, _x8) { return _addDll_runAfterPrompt.apply(this, arguments); } function _addDll_runAfterPrompt() { _addDll_runAfterPrompt = (0, _asyncToGenerator2.default)(function* (cmd, answers, { config, configPath }) { const _answers = (0, _slicedToArray2.default)(answers, 2), options = _answers[1]; let dllOutputPath = options.$path; if (!_path.default.isAbsolute(dllOutputPath)) { dllOutputPath = new _config.WebpackOption({ pathSensitive: true, value: options.$path }); } let dllPluginPath = options.$path; if (!_path.default.isAbsolute(dllPluginPath)) { dllPluginPath = new _config.WebpackOption({ pathSensitive: true, value: [options.$path, "[name].json"] }); } const dllConfig = new _config.WebpackConfig({ configuration: { context: config.getOption("context"), entry: { library: discoveredVendorModules }, output: { path: dllOutputPath, filename: options.$outputFilename, library: "[name]" } }, plugins: [new _config.WebpackPlugin({ type: _config.WebpackPlugin.type.DLL, name: "webpack.DllPlugin", dependency: new _config.WebpackDependency({ package: "webpack", identifier: "webpack" }), arguments: [{ name: "[name]", path: dllPluginPath }] })] }); let manifestPath = options.$path; if (!_path.default.isAbsolute(manifestPath)) { manifestPath = options.$path + `/library.json`; if (!(0, _startsWith.default)(manifestPath, ".")) { manifestPath = "./" + manifestPath; } } const context = _config.WebpackOption.fromSource(`__dirname`); const manifest = _config.WebpackOption.fromSource(`require("${manifestPath}")`); config.addPlugin(new _config.WebpackPlugin({ type: _config.WebpackPlugin.type.DLL_REFERENCE, name: "webpack.DllReferencePlugin", arguments: [{ context, manifest }], dependency: new _config.WebpackDependency({ package: "webpack", identifier: "webpack" }) })); if (cmd.dryRun) { (0, _logger.default)(); cmd.configName = "dll config"; (0, _utilities.printConfig)(dllConfig, cmd); return; } let dllConfigPath = options.$configFilename; if (!_path.default.isAbsolute(dllConfigPath)) { dllConfigPath = _path.default.resolve(_path.default.dirname(configPath), dllConfigPath); } global.wpk.try("to write the dll config", () => { _fs.default.writeFileSync(dllConfigPath, dllConfig.toString()); }); if (!cmd.yes) { (0, _logger.default)(); } const filename = _path.default.basename(dllConfigPath); _logger.default.info("dll config created at", dllConfigPath); _logger.default.info("DllReferencePlugin added to", _path.default.basename(configPath)); _logger.default.info(_chalk.default`to build dll run {grey wpk build ${filename}}`); }); return _addDll_runAfterPrompt.apply(this, arguments); } var _default = new _prompt.default({ name: "add-dll", message: "Creating new dll config:", persistable: true, runBeforePrompt: addDll_runBeforePrompt, runAfterPrompt: addDll_runAfterPrompt, defaultAnswers, questions }); exports.default = _default;