@wpk-cli/command-add
Version:
@wpk-cli/command-add
508 lines (417 loc) • 14.8 kB
JavaScript
;
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;