diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000000..e6f9a9d4087 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,79 @@ +module.exports = { + "root": true, + "plugins": ["node", "prettier"], + "extends": ["eslint:recommended", "plugin:node/recommended"], + "env": { + "node": true, + "es6": true, + "jest": true + }, + "parserOptions": { "ecmaVersion": 2017 }, + "rules": { + "quote-props": ["error", "as-needed"], + "no-dupe-keys": "error", + "quotes": ["error", "double"], + "no-undef": "error", + "no-extra-semi": "error", + "semi": "error", + "no-template-curly-in-string": "error", + "no-caller": "error", + "yoda": "error", + "eqeqeq": "error", + "global-require": "off", + "brace-style": "error", + "key-spacing": "error", + "space-in-parens": ["error", "never"], + "space-infix-ops": "error", + "indent": ["error", "tab", { "SwitchCase": 1 }], + "no-extra-bind": "warn", + "no-empty": "off", + "no-multiple-empty-lines": "error", + "no-multi-spaces": "error", + "no-process-exit": "off", + "no-trailing-spaces": "error", + "no-use-before-define": "off", + "no-unused-vars": ["error", { "args": "none" }], + "no-unsafe-negation": "error", + "no-loop-func": "warn", + "space-before-function-paren": ["error", "never"], + "space-before-blocks": "error", + "object-curly-spacing": ["error", "always"], + "keyword-spacing": ["error", { + "after": true, + "overrides": { + "const": { "after": true }, + "try": { "after": true }, + "catch": { "after": true }, + "if": { "after": true }, + "else": { "after": true }, + "throw": { "after": true }, + "case": { "after": true }, + "return": { "after": true }, + "finally": { "after": true }, + "do": { "after": true } + } + }], + "no-console": "off", + "valid-jsdoc": "error", + "node/no-unsupported-features": ["error", { "version": 4 }], + "node/no-deprecated-api": "error", + "node/no-missing-import": "error", + "node/no-missing-require": [ + "error", + { + "allowModules": [ + "webpack" + ] + } + ], + "node/no-unpublished-bin": "error", + "node/no-unpublished-require": "error", + "eol-last": ["error", "always"], + "newline-per-chained-call": "off", + "node/process-exit-as-throw": "error", + "prettier/prettier": ["error", { + "useTabs": true, + "bracketSpacing": false + }] + } +}; diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 0f9922f37e8..00000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "parser": "babel-eslint", - "env": { - "node": true, - "commonjs": true, - "es6": true, - "jest": true - }, - "extends": "eslint:recommended", - "plugins": [ - "node" - ], - "rules": { - "indent": [ - "error", - "tab" - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ], - "no-unused-vars": 1, - "no-console": 0, - "node/exports-style": [ - "error", - "module.exports" - ], - "node/no-unsupported-features": "error", - "node/no-deprecated-api": "error", - "node/no-missing-import": "error", - "node/no-missing-require": [ - "error", - { - "allowModules": [ - "webpack" - ] - } - ], - "node/no-unpublished-bin": "error", - "node/no-unpublished-require": "error", - "node/process-exit-as-throw": "error" - } -} diff --git a/.jsbeautifyrc b/.jsbeautifyrc deleted file mode 100644 index 79b04984674..00000000000 --- a/.jsbeautifyrc +++ /dev/null @@ -1,25 +0,0 @@ -{ - "js": { - "allowed_file_extensions": ["js", "json", "jshintrc", "jsbeautifyrc"], - "brace_style": "collapse", - "break_chained_methods": false, - "e4x": true, - "eval_code": false, - "end_with_newline": true, - "indent_char": "\t", - "indent_level": 0, - "indent_size": 1, - "indent_with_tabs": true, - "jslint_happy": false, - "jslint_happy_align_switch_case": true, - "space_after_anon_function": false, - "keep_array_indentation": false, - "keep_function_indentation": false, - "max_preserve_newlines": 2, - "preserve_newlines": true, - "space_before_conditional": false, - "space_in_paren": false, - "unescape_strings": false, - "wrap_line_length": 0 - } -} \ No newline at end of file diff --git a/__mocks__/creator/validate-options.mock.js b/__mocks__/creator/validate-options.mock.js index 593f51f2f6f..751bb1c7815 100644 --- a/__mocks__/creator/validate-options.mock.js +++ b/__mocks__/creator/validate-options.mock.js @@ -1,17 +1,19 @@ -const fs = require('fs'); -const path = require('path'); +"use strict"; + +const fs = require("fs"); +const path = require("path"); function getPath(part) { return path.join(process.cwd(), part); } function validateOptions(opts) { - return Object.keys(opts).forEach( (location) => { + return Object.keys(opts).forEach((location) => { let part = getPath(opts[location]); try { fs.readFileSync(part); - } catch (err) { - throw new Error('Did not find the file'); + } catch(err) { + throw new Error("Did not find the file"); } }); } diff --git a/__mocks__/inquirer/resolve.mock.js b/__mocks__/inquirer/resolve.mock.js index ac47b722773..26265abbd33 100644 --- a/__mocks__/inquirer/resolve.mock.js +++ b/__mocks__/inquirer/resolve.mock.js @@ -1,27 +1,29 @@ -'use strict'; -const path = require('path'); +"use strict"; + +const path = require("path"); function mockPromise(value) { return (value || {}).then ? value : { - then: function (callback) { + then: function(callback) { return mockPromise(callback(value)); } }; } + function spawnChild(pkg) { return pkg; } function getLoc(option) { let packageModule = []; - option.filter( (pkg) => { - mockPromise(spawnChild(pkg)).then( () => { + option.filter((pkg) => { + mockPromise(spawnChild(pkg)).then(() => { try { - let loc = path.join('..', '..', 'node_modules', pkg); + let loc = path.join("..", "..", "node_modules", pkg); packageModule.push(loc); } catch(err) { - throw new Error('Package wasn\'t validated correctly..' + - 'Submit an issue for', pkg, 'if this persists'); + throw new Error("Package wasn't validated correctly.." + + "Submit an issue for", pkg, "if this persists"); } }); return packageModule; diff --git a/bin/.eslintrc.json b/bin/.eslintrc.json new file mode 100644 index 00000000000..8a7d65b183a --- /dev/null +++ b/bin/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "node/no-missing-require": 0 + } +} diff --git a/bin/config-yargs.js b/bin/config-yargs.js index a9363f40659..1c6ed91c397 100644 --- a/bin/config-yargs.js +++ b/bin/config-yargs.js @@ -1,283 +1,285 @@ -var CONFIG_GROUP = 'Config options:'; -var BASIC_GROUP = 'Basic options:'; -var MODULE_GROUP = 'Module options:'; -var OUTPUT_GROUP = 'Output options:'; -var ADVANCED_GROUP = 'Advanced options:'; -var RESOLVE_GROUP = 'Resolving options:'; -var OPTIMIZE_GROUP = 'Optimizing options:'; -var INIT_GROUP = 'Initialization:'; +"use strict"; + +var CONFIG_GROUP = "Config options:"; +var BASIC_GROUP = "Basic options:"; +var MODULE_GROUP = "Module options:"; +var OUTPUT_GROUP = "Output options:"; +var ADVANCED_GROUP = "Advanced options:"; +var RESOLVE_GROUP = "Resolving options:"; +var OPTIMIZE_GROUP = "Optimizing options:"; +var INIT_GROUP = "Initialization:"; module.exports = function(yargs) { yargs - .help('help') - .alias('help', 'h', '?') + .help("help") + .alias("help", "h", "?") .version() - .alias('version', 'v') + .alias("version", "v") .options({ - 'init': { - type: 'boolean', - describe: 'Initializes a new webpack configuration or loads a' + '\n' + - 'plugin if specified', + "init": { + type: "boolean", + describe: "Initializes a new webpack configuration or loads a" + "\n" + + "plugin if specified", group: INIT_GROUP }, - 'migrate': { - type: 'boolean', - describe: 'Migrate your webpack configuration from webpack 1 to webpack 2', + "migrate": { + type: "boolean", + describe: "Migrate your webpack configuration from webpack 1 to webpack 2", group: INIT_GROUP }, - 'config': { - type: 'string', - describe: 'Path to the config file', + "config": { + type: "string", + describe: "Path to the config file", group: CONFIG_GROUP, - defaultDescription: 'webpack.config.js or webpackfile.js', + defaultDescription: "webpack.config.js or webpackfile.js", requiresArg: true }, - 'env': { - describe: 'Enviroment passed to the config, when it is a function', + "env": { + describe: "Enviroment passed to the config, when it is a function", group: CONFIG_GROUP }, - 'context': { - type: 'string', - describe: 'The root directory for resolving entry point and stats', + "context": { + type: "string", + describe: "The root directory for resolving entry point and stats", group: BASIC_GROUP, - defaultDescription: 'The current directory', + defaultDescription: "The current directory", requiresArg: true }, - 'entry': { - type: 'string', - describe: 'The entry point', + "entry": { + type: "string", + describe: "The entry point", group: BASIC_GROUP, requiresArg: true }, - 'module-bind': { - type: 'string', - describe: 'Bind an extension to a loader', + "module-bind": { + type: "string", + describe: "Bind an extension to a loader", group: MODULE_GROUP, requiresArg: true }, - 'module-bind-post': { - type: 'string', - describe: '', + "module-bind-post": { + type: "string", + describe: "", group: MODULE_GROUP, requiresArg: true }, - 'module-bind-pre': { - type: 'string', - describe: '', + "module-bind-pre": { + type: "string", + describe: "", group: MODULE_GROUP, requiresArg: true }, - 'output-path': { - type: 'string', - describe: 'The output path for compilation assets', + "output-path": { + type: "string", + describe: "The output path for compilation assets", group: OUTPUT_GROUP, - defaultDescription: 'The current directory', + defaultDescription: "The current directory", requiresArg: true }, - 'output-filename': { - type: 'string', - describe: 'The output filename of the bundle', + "output-filename": { + type: "string", + describe: "The output filename of the bundle", group: OUTPUT_GROUP, - defaultDescription: '[name].js', + defaultDescription: "[name].js", requiresArg: true }, - 'output-chunk-filename': { - type: 'string', - describe: 'The output filename for additional chunks', + "output-chunk-filename": { + type: "string", + describe: "The output filename for additional chunks", group: OUTPUT_GROUP, - defaultDescription: 'filename with [id] instead of [name] or [id] prefixed', + defaultDescription: "filename with [id] instead of [name] or [id] prefixed", requiresArg: true }, - 'output-source-map-filename': { - type: 'string', - describe: 'The output filename for the SourceMap', + "output-source-map-filename": { + type: "string", + describe: "The output filename for the SourceMap", group: OUTPUT_GROUP, requiresArg: true }, - 'output-public-path': { - type: 'string', - describe: 'The public path for the assets', + "output-public-path": { + type: "string", + describe: "The public path for the assets", group: OUTPUT_GROUP, requiresArg: true }, - 'output-jsonp-function': { - type: 'string', - describe: 'The name of the jsonp function used for chunk loading', + "output-jsonp-function": { + type: "string", + describe: "The name of the jsonp function used for chunk loading", group: OUTPUT_GROUP, requiresArg: true }, - 'output-pathinfo': { - type: 'boolean', - describe: 'Include a comment with the request for every dependency (require, import, etc.)', + "output-pathinfo": { + type: "boolean", + describe: "Include a comment with the request for every dependency (require, import, etc.)", group: OUTPUT_GROUP }, - 'output-library': { - type: 'string', - describe: 'Expose the exports of the entry point as library', + "output-library": { + type: "string", + describe: "Expose the exports of the entry point as library", group: OUTPUT_GROUP, requiresArg: true }, - 'output-library-target': { - type: 'string', - describe: 'The type for exposing the exports of the entry point as library', + "output-library-target": { + type: "string", + describe: "The type for exposing the exports of the entry point as library", group: OUTPUT_GROUP, requiresArg: true }, - 'records-input-path': { - type: 'string', - describe: 'Path to the records file (reading)', + "records-input-path": { + type: "string", + describe: "Path to the records file (reading)", group: ADVANCED_GROUP, requiresArg: true }, - 'records-output-path': { - type: 'string', - describe: 'Path to the records file (writing)', + "records-output-path": { + type: "string", + describe: "Path to the records file (writing)", group: ADVANCED_GROUP, requiresArg: true }, - 'records-path': { - type: 'string', - describe: 'Path to the records file', + "records-path": { + type: "string", + describe: "Path to the records file", group: ADVANCED_GROUP, requiresArg: true }, - 'define': { - type: 'string', - describe: 'Define any free var in the bundle', + "define": { + type: "string", + describe: "Define any free var in the bundle", group: ADVANCED_GROUP, requiresArg: true }, - 'target': { - type: 'string', - describe: 'The targeted execution enviroment', + "target": { + type: "string", + describe: "The targeted execution enviroment", group: ADVANCED_GROUP, requiresArg: true }, - 'cache': { - type: 'boolean', - describe: 'Enable in memory caching', + "cache": { + type: "boolean", + describe: "Enable in memory caching", default: null, group: ADVANCED_GROUP, - defaultDescription: 'It\'s enabled by default when watching' + defaultDescription: "It's enabled by default when watching" }, - 'watch': { - type: 'boolean', - alias: 'w', - describe: 'Watch the filesystem for changes', + "watch": { + type: "boolean", + alias: "w", + describe: "Watch the filesystem for changes", group: BASIC_GROUP }, - 'save': { - type: 'boolean', - alias: 's', - describe: 'Rebuilds on save regardless of changes in watch mode', + "save": { + type: "boolean", + alias: "s", + describe: "Rebuilds on save regardless of changes in watch mode", group: BASIC_GROUP }, - 'watch-stdin': { - type: 'boolean', - alias: 'stdin', - describe: 'Exit the process when stdin is closed', + "watch-stdin": { + type: "boolean", + alias: "stdin", + describe: "Exit the process when stdin is closed", group: ADVANCED_GROUP }, - 'watch-aggregate-timeout': { - describe: 'Timeout for gathering changes while watching', + "watch-aggregate-timeout": { + describe: "Timeout for gathering changes while watching", group: ADVANCED_GROUP, requiresArg: true }, - 'watch-poll': { - type: 'boolean', - describe: 'The polling intervall for watching (also enable polling)', + "watch-poll": { + type: "boolean", + describe: "The polling intervall for watching (also enable polling)", group: ADVANCED_GROUP }, - 'hot': { - type: 'boolean', - describe: 'Enables Hot Module Replacement', + "hot": { + type: "boolean", + describe: "Enables Hot Module Replacement", group: ADVANCED_GROUP }, - 'debug': { - type: 'boolean', - describe: 'Switch loaders to debug mode', + "debug": { + type: "boolean", + describe: "Switch loaders to debug mode", group: BASIC_GROUP }, - 'devtool': { - type: 'string', - describe: 'Enable devtool for better debugging experience (Example: --devtool eval-cheap-module-source-map)', + "devtool": { + type: "string", + describe: "Enable devtool for better debugging experience (Example: --devtool eval-cheap-module-source-map)", group: BASIC_GROUP, requiresArg: true }, - 'resolve-alias': { - type: 'string', - describe: 'Setup a module alias for resolving (Example: jquery-plugin=jquery.plugin)', + "resolve-alias": { + type: "string", + describe: "Setup a module alias for resolving (Example: jquery-plugin=jquery.plugin)", group: RESOLVE_GROUP, requiresArg: true }, - 'resolve-extensions': { - 'type': 'array', - describe: 'Setup extensions that should be used to resolve modules (Example: --resolve-extensions .es6 .js)', + "resolve-extensions": { + "type": "array", + describe: "Setup extensions that should be used to resolve modules (Example: --resolve-extensions .es6 .js)", group: RESOLVE_GROUP, requiresArg: true }, - 'resolve-loader-alias': { - type: 'string', - describe: 'Setup a loader alias for resolving', + "resolve-loader-alias": { + type: "string", + describe: "Setup a loader alias for resolving", group: RESOLVE_GROUP, requiresArg: true }, - 'optimize-max-chunks': { - describe: 'Try to keep the chunk count below a limit', + "optimize-max-chunks": { + describe: "Try to keep the chunk count below a limit", group: OPTIMIZE_GROUP, requiresArg: true }, - 'optimize-min-chunk-size': { - describe: 'Try to keep the chunk size above a limit', + "optimize-min-chunk-size": { + describe: "Try to keep the chunk size above a limit", group: OPTIMIZE_GROUP, requiresArg: true }, - 'optimize-minimize': { - type: 'boolean', - describe: 'Minimize javascript and switches loaders to minimizing', + "optimize-minimize": { + type: "boolean", + describe: "Minimize javascript and switches loaders to minimizing", group: OPTIMIZE_GROUP }, - 'prefetch': { - type: 'string', - describe: 'Prefetch this request (Example: --prefetch ./file.js)', + "prefetch": { + type: "string", + describe: "Prefetch this request (Example: --prefetch ./file.js)", group: ADVANCED_GROUP, requiresArg: true }, - 'provide': { - type: 'string', - describe: 'Provide these modules as free vars in all modules (Example: --provide jQuery=jquery)', + "provide": { + type: "string", + describe: "Provide these modules as free vars in all modules (Example: --provide jQuery=jquery)", group: ADVANCED_GROUP, requiresArg: true }, - 'labeled-modules': { - type: 'boolean', - describe: 'Enables labeled modules', + "labeled-modules": { + type: "boolean", + describe: "Enables labeled modules", group: ADVANCED_GROUP }, - 'plugin': { - type: 'string', - describe: 'Load this plugin', + "plugin": { + type: "string", + describe: "Load this plugin", group: ADVANCED_GROUP, requiresArg: true }, - 'bail': { - type: 'boolean', - describe: 'Abort the compilation on first error', + "bail": { + type: "boolean", + describe: "Abort the compilation on first error", group: ADVANCED_GROUP }, - 'profile': { - type: 'boolean', - describe: 'Profile the compilation and include information in stats', + "profile": { + type: "boolean", + describe: "Profile the compilation and include information in stats", group: ADVANCED_GROUP }, - 'd': { - type: 'boolean', - describe: 'shortcut for --debug --devtool eval-cheap-module-source-map --output-pathinfo', + "d": { + type: "boolean", + describe: "shortcut for --debug --devtool eval-cheap-module-source-map --output-pathinfo", group: BASIC_GROUP }, - 'p': { - type: 'boolean', - describe: 'shortcut for --optimize-minimize --define process.env.NODE_ENV=\'production\'', + "p": { + type: "boolean", + describe: "shortcut for --optimize-minimize --define process.env.NODE_ENV='production'", group: BASIC_GROUP } }).strict(); diff --git a/bin/convert-argv.js b/bin/convert-argv.js index e3e004f652b..c52fc33da53 100644 --- a/bin/convert-argv.js +++ b/bin/convert-argv.js @@ -1,7 +1,9 @@ -var path = require('path'); -var fs = require('fs'); +"use strict"; + +var path = require("path"); +var fs = require("fs"); fs.existsSync = fs.existsSync || path.existsSync; -var interpret = require('interpret'); +var interpret = require("interpret"); module.exports = function(yargs, argv, convertOptions) { @@ -10,22 +12,22 @@ module.exports = function(yargs, argv, convertOptions) { // Shortcuts if(argv.d) { argv.debug = true; - argv['output-pathinfo'] = true; + argv["output-pathinfo"] = true; if(!argv.devtool) { - argv.devtool = 'eval-cheap-module-source-map'; + argv.devtool = "eval-cheap-module-source-map"; } } if(argv.p) { - argv['optimize-minimize'] = true; - argv['define'] = [].concat(argv['define'] || []).concat('process.env.NODE_ENV=\'production\''); + argv["optimize-minimize"] = true; + argv["define"] = [].concat(argv["define"] || []).concat("process.env.NODE_ENV='production'"); } var configFileLoaded = false; var configFiles = []; var extensions = Object.keys(interpret.extensions).sort(function(a, b) { - return a === '.js' ? -1 : b === '.js' ? 1 : a.length - b.length; + return a === ".js" ? -1 : b === ".js" ? 1 : a.length - b.length; }); - var defaultConfigFiles = ['webpack.config', 'webpackfile'].map(function(filename) { + var defaultConfigFiles = ["webpack.config", "webpackfile"].map(function(filename) { return extensions.map(function(ext) { return { path: path.resolve(filename + ext), @@ -75,7 +77,7 @@ module.exports = function(yargs, argv, convertOptions) { if(configFiles.length > 0) { var registerCompiler = function registerCompiler(moduleDescriptor) { if(moduleDescriptor) { - if(typeof moduleDescriptor === 'string') { + if(typeof moduleDescriptor === "string") { require(moduleDescriptor); } else if(!Array.isArray(moduleDescriptor)) { moduleDescriptor.register(require(moduleDescriptor.module)); @@ -95,9 +97,9 @@ module.exports = function(yargs, argv, convertOptions) { var requireConfig = function requireConfig(configPath) { var options = require(configPath); var isES6DefaultExportedFunc = ( - typeof options === 'object' && options !== null && typeof options.default === 'function' + typeof options === "object" && options !== null && typeof options.default === "function" ); - if(typeof options === 'function' || isES6DefaultExportedFunc) { + if(typeof options === "function" || isES6DefaultExportedFunc) { options = isES6DefaultExportedFunc ? options.default : options; options = options(argv.env, argv); } @@ -120,18 +122,18 @@ module.exports = function(yargs, argv, convertOptions) { } function processConfiguredOptions(options) { - if(options === null || typeof options !== 'object') { - console.error('Config did not export an object or a function returning an object.'); + if(options === null || typeof options !== "object") { + console.error("Config did not export an object or a function returning an object."); process.exit(-1); } // process Promise - if(typeof options.then === 'function') { + if(typeof options.then === "function") { return options.then(processConfiguredOptions); } // process ES6 default - if(typeof options === 'object' && typeof options.default === 'object') { + if(typeof options === "object" && typeof options.default === "object") { return processConfiguredOptions(options.default); } @@ -152,20 +154,20 @@ module.exports = function(yargs, argv, convertOptions) { options.watch = true; } - if(argv['watch-aggregate-timeout']) { + if(argv["watch-aggregate-timeout"]) { options.watchOptions = options.watchOptions || {}; - options.watchOptions.aggregateTimeout = +argv['watch-aggregate-timeout']; + options.watchOptions.aggregateTimeout = +argv["watch-aggregate-timeout"]; } - if(argv['watch-poll']) { + if(argv["watch-poll"]) { options.watchOptions = options.watchOptions || {}; - if(typeof argv['watch-poll'] !== 'boolean') - options.watchOptions.poll = +argv['watch-poll']; + if(typeof argv["watch-poll"] !== "boolean") + options.watchOptions.poll = +argv["watch-poll"]; else options.watchOptions.poll = true; } - if(argv['watch-stdin']) { + if(argv["watch-stdin"]) { options.watchOptions = options.watchOptions || {}; options.watchOptions.stdin = true; options.watch = true; @@ -186,7 +188,7 @@ module.exports = function(yargs, argv, convertOptions) { if(finalize) { finalize(); } - } else if(typeof argv[name] !== 'undefined' && argv[name] !== null) { + } else if(typeof argv[name] !== "undefined" && argv[name] !== null) { if(init) { init(); } @@ -199,7 +201,7 @@ module.exports = function(yargs, argv, convertOptions) { function ifArgPair(name, fn, init, finalize) { ifArg(name, function(content, idx) { - var i = content.indexOf('='); + var i = content.indexOf("="); if(i < 0) { return fn(null, content, idx); } else { @@ -232,44 +234,44 @@ module.exports = function(yargs, argv, convertOptions) { } function loadPlugin(name) { - var loadUtils = require('loader-utils'); + var loadUtils = require("loader-utils"); var args = null; try { - var p = name && name.indexOf('?'); + var p = name && name.indexOf("?"); if(p > -1) { args = loadUtils.parseQuery(name.substring(p)); name = name.substring(0, p); } } catch(e) { - console.log('Invalid plugin arguments ' + name + ' (' + e + ').'); + console.log("Invalid plugin arguments " + name + " (" + e + ")."); process.exit(-1); } var path; try { - var resolve = require('enhanced-resolve'); + var resolve = require("enhanced-resolve"); path = resolve.sync(process.cwd(), name); } catch(e) { - console.log('Cannot resolve plugin ' + name + '.'); + console.log("Cannot resolve plugin " + name + "."); process.exit(-1); } var Plugin; try { Plugin = require(path); } catch(e) { - console.log('Cannot load plugin ' + name + '. (' + path + ')'); + console.log("Cannot load plugin " + name + ". (" + path + ")"); throw e; } try { return new Plugin(args); } catch(e) { - console.log('Cannot instantiate plugin ' + name + '. (' + path + ')'); + console.log("Cannot instantiate plugin " + name + ". (" + path + ")"); throw e; } } function ensureObject(parent, name) { - if(typeof parent[name] !== 'object' || parent[name] === null) { + if(typeof parent[name] !== "object" || parent[name] === null) { parent[name] = {}; } } @@ -280,33 +282,33 @@ module.exports = function(yargs, argv, convertOptions) { } } - ifArgPair('entry', function(name, entry) { + ifArgPair("entry", function(name, entry) { options.entry[name] = entry; }, function() { - ensureObject(options, 'entry'); + ensureObject(options, "entry"); }); function bindLoaders(arg, collection) { ifArgPair(arg, function(name, binding) { if(name === null) { name = binding; - binding += '-loader'; + binding += "-loader"; } options.module[collection].push({ - test: new RegExp('\\.' + name.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') + '$'), + test: new RegExp("\\." + name.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + "$"), loader: binding }); }, function() { - ensureObject(options, 'module'); + ensureObject(options, "module"); ensureArray(options.module, collection); }); } - bindLoaders('module-bind', 'loaders'); - bindLoaders('module-bind-pre', 'preLoaders'); - bindLoaders('module-bind-post', 'postLoaders'); + bindLoaders("module-bind", "loaders"); + bindLoaders("module-bind-pre", "preLoaders"); + bindLoaders("module-bind-post", "postLoaders"); var defineObject; - ifArgPair('define', function(name, value) { + ifArgPair("define", function(name, value) { if(name === null) { name = value; value = true; @@ -315,108 +317,108 @@ module.exports = function(yargs, argv, convertOptions) { }, function() { defineObject = {}; }, function() { - ensureArray(options, 'plugins'); - var DefinePlugin = require('webpack/lib/DefinePlugin'); + ensureArray(options, "plugins"); + var DefinePlugin = require("webpack/lib/DefinePlugin"); options.plugins.push(new DefinePlugin(defineObject)); }); - ifArg('output-path', function(value) { - ensureObject(options, 'output'); + ifArg("output-path", function(value) { + ensureObject(options, "output"); options.output.path = value; }); - ifArg('output-filename', function(value) { - ensureObject(options, 'output'); + ifArg("output-filename", function(value) { + ensureObject(options, "output"); options.output.filename = value; noOutputFilenameDefined = false; }); - ifArg('output-chunk-filename', function(value) { - ensureObject(options, 'output'); + ifArg("output-chunk-filename", function(value) { + ensureObject(options, "output"); options.output.chunkFilename = value; }); - ifArg('output-source-map-filename', function(value) { - ensureObject(options, 'output'); + ifArg("output-source-map-filename", function(value) { + ensureObject(options, "output"); options.output.sourceMapFilename = value; }); - ifArg('output-public-path', function(value) { - ensureObject(options, 'output'); + ifArg("output-public-path", function(value) { + ensureObject(options, "output"); options.output.publicPath = value; }); - ifArg('output-jsonp-function', function(value) { - ensureObject(options, 'output'); + ifArg("output-jsonp-function", function(value) { + ensureObject(options, "output"); options.output.jsonpFunction = value; }); - ifBooleanArg('output-pathinfo', function() { - ensureObject(options, 'output'); + ifBooleanArg("output-pathinfo", function() { + ensureObject(options, "output"); options.output.pathinfo = true; }); - ifArg('output-library', function(value) { - ensureObject(options, 'output'); + ifArg("output-library", function(value) { + ensureObject(options, "output"); options.output.library = value; }); - ifArg('output-library-target', function(value) { - ensureObject(options, 'output'); + ifArg("output-library-target", function(value) { + ensureObject(options, "output"); options.output.libraryTarget = value; }); - ifArg('records-input-path', function(value) { + ifArg("records-input-path", function(value) { options.recordsInputPath = path.resolve(value); }); - ifArg('records-output-path', function(value) { + ifArg("records-output-path", function(value) { options.recordsOutputPath = path.resolve(value); }); - ifArg('records-path', function(value) { + ifArg("records-path", function(value) { options.recordsPath = path.resolve(value); }); - ifArg('target', function(value) { + ifArg("target", function(value) { options.target = value; }); - mapArgToBoolean('cache'); + mapArgToBoolean("cache"); - ifBooleanArg('hot', function() { - ensureArray(options, 'plugins'); - var HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin'); + ifBooleanArg("hot", function() { + ensureArray(options, "plugins"); + var HotModuleReplacementPlugin = require("webpack/lib/HotModuleReplacementPlugin"); options.plugins.push(new HotModuleReplacementPlugin()); }); - ifBooleanArg('debug', function() { - ensureArray(options, 'plugins'); - var LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin'); + ifBooleanArg("debug", function() { + ensureArray(options, "plugins"); + var LoaderOptionsPlugin = require("webpack/lib/LoaderOptionsPlugin"); options.plugins.push(new LoaderOptionsPlugin({ debug: true })); }); - ifArg('devtool', function(value) { + ifArg("devtool", function(value) { options.devtool = value; }); function processResolveAlias(arg, key) { ifArgPair(arg, function(name, value) { if(!name) { - throw new Error('--' + arg + ' ='); + throw new Error("--" + arg + " ="); } ensureObject(options, key); - ensureObject(options[key], 'alias'); + ensureObject(options[key], "alias"); options[key].alias[name] = value; }); } - processResolveAlias('resolve-alias', 'resolve'); - processResolveAlias('resolve-loader-alias', 'resolveLoader'); + processResolveAlias("resolve-alias", "resolve"); + processResolveAlias("resolve-loader-alias", "resolveLoader"); - ifArg('resolve-extensions', function(value) { - ensureObject(options, 'resolve'); + ifArg("resolve-extensions", function(value) { + ensureObject(options, "resolve"); if(Array.isArray(value)) { options.resolve.extensions = value; } else { @@ -424,43 +426,43 @@ module.exports = function(yargs, argv, convertOptions) { } }); - ifArg('optimize-max-chunks', function(value) { - ensureArray(options, 'plugins'); - var LimitChunkCountPlugin = require('webpack/lib/optimize/LimitChunkCountPlugin'); + ifArg("optimize-max-chunks", function(value) { + ensureArray(options, "plugins"); + var LimitChunkCountPlugin = require("webpack/lib/optimize/LimitChunkCountPlugin"); options.plugins.push(new LimitChunkCountPlugin({ maxChunks: parseInt(value, 10) })); }); - ifArg('optimize-min-chunk-size', function(value) { - ensureArray(options, 'plugins'); - var MinChunkSizePlugin = require('webpack/lib/optimize/MinChunkSizePlugin'); + ifArg("optimize-min-chunk-size", function(value) { + ensureArray(options, "plugins"); + var MinChunkSizePlugin = require("webpack/lib/optimize/MinChunkSizePlugin"); options.plugins.push(new MinChunkSizePlugin({ minChunkSize: parseInt(value, 10) })); }); - ifBooleanArg('optimize-minimize', function() { - ensureArray(options, 'plugins'); - var UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin'); - var LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin'); + ifBooleanArg("optimize-minimize", function() { + ensureArray(options, "plugins"); + var UglifyJsPlugin = require("webpack/lib/optimize/UglifyJsPlugin"); + var LoaderOptionsPlugin = require("webpack/lib/LoaderOptionsPlugin"); options.plugins.push(new UglifyJsPlugin({ - sourceMap: options.devtool && (options.devtool.indexOf('sourcemap') >= 0 || options.devtool.indexOf('source-map') >= 0) + sourceMap: options.devtool && (options.devtool.indexOf("sourcemap") >= 0 || options.devtool.indexOf("source-map") >= 0) })); options.plugins.push(new LoaderOptionsPlugin({ minimize: true })); }); - ifArg('prefetch', function(request) { - ensureArray(options, 'plugins'); - var PrefetchPlugin = require('webpack/PrefetchPlugin'); + ifArg("prefetch", function(request) { + ensureArray(options, "plugins"); + var PrefetchPlugin = require("webpack/PrefetchPlugin"); options.plugins.push(new PrefetchPlugin(request)); }); - ifArg('provide', function(value) { - ensureArray(options, 'plugins'); - var idx = value.indexOf('='); + ifArg("provide", function(value) { + ensureArray(options, "plugins"); + var idx = value.indexOf("="); var name; if(idx >= 0) { name = value.substr(0, idx); @@ -468,27 +470,27 @@ module.exports = function(yargs, argv, convertOptions) { } else { name = value; } - var ProvidePlugin = require('webpack/ProvidePlugin'); + var ProvidePlugin = require("webpack/ProvidePlugin"); options.plugins.push(new ProvidePlugin(name, value)); }); - ifBooleanArg('labeled-modules', function() { - ensureArray(options, 'plugins'); - var LabeledModulesPlugin = require('webpack/lib/dependencies/LabeledModulesPlugin'); + ifBooleanArg("labeled-modules", function() { + ensureArray(options, "plugins"); + var LabeledModulesPlugin = require("webpack/lib/dependencies/LabeledModulesPlugin"); options.plugins.push(new LabeledModulesPlugin()); }); - ifArg('plugin', function(value) { - ensureArray(options, 'plugins'); + ifArg("plugin", function(value) { + ensureArray(options, "plugins"); options.plugins.push(loadPlugin(value)); }); - mapArgToBoolean('bail'); + mapArgToBoolean("bail"); - mapArgToBoolean('profile'); + mapArgToBoolean("profile"); if(noOutputFilenameDefined) { - ensureObject(options, 'output'); + ensureObject(options, "output"); if(convertOptions && convertOptions.outputFilename) { options.output.path = path.dirname(convertOptions.outputFilename); options.output.filename = path.basename(convertOptions.outputFilename); @@ -497,22 +499,22 @@ module.exports = function(yargs, argv, convertOptions) { options.output.path = path.dirname(options.output.filename); options.output.filename = path.basename(options.output.filename); } else if(configFileLoaded) { - throw new Error('\'output.filename\' is required, either in config file or as --output-filename'); + throw new Error("'output.filename' is required, either in config file or as --output-filename"); } else { - console.error('No configuration file found and no output filename configured via CLI option.'); - console.error('A configuration file could be named \'webpack.config.js\' in the current directory.'); - console.error('Use --help to display the CLI options.'); + console.error("No configuration file found and no output filename configured via CLI option."); + console.error("A configuration file could be named 'webpack.config.js' in the current directory."); + console.error("Use --help to display the CLI options."); process.exit(-1); } } if(argv._.length > 0) { - if(Array.isArray(options.entry) || typeof options.entry === 'string') { + if(Array.isArray(options.entry) || typeof options.entry === "string") { options.entry = { main: options.entry }; } - ensureObject(options, 'entry'); + ensureObject(options, "entry"); var addTo = function addTo(name, entry) { if(options.entry[name]) { @@ -525,14 +527,14 @@ module.exports = function(yargs, argv, convertOptions) { } }; argv._.forEach(function(content) { - var i = content.indexOf('='); - var j = content.indexOf('?'); + var i = content.indexOf("="); + var j = content.indexOf("?"); if(i < 0 || (j >= 0 && j < i)) { var resolved = path.resolve(content); if(fs.existsSync(resolved)) { - addTo('main', resolved); + addTo("main", resolved); } else { - addTo('main', content); + addTo("main", content); } } else { addTo(content.substr(0, i), content.substr(i + 1)); @@ -542,13 +544,13 @@ module.exports = function(yargs, argv, convertOptions) { if(!options.entry) { if(configFileLoaded) { - console.error('Configuration file found but no entry configured.'); + console.error("Configuration file found but no entry configured."); } else { - console.error('No configuration file found and no entry configured via CLI option.'); - console.error('When using the CLI you need to provide at least two arguments: entry and output.'); - console.error('A configuration file could be named \'webpack.config.js\' in the current directory.'); + console.error("No configuration file found and no entry configured via CLI option."); + console.error("When using the CLI you need to provide at least two arguments: entry and output."); + console.error("A configuration file could be named 'webpack.config.js' in the current directory."); } - console.error('Use --help to display the CLI options.'); + console.error("Use --help to display the CLI options."); process.exit(-1); } } diff --git a/bin/process-options.js b/bin/process-options.js index 764c560546d..b47107a8e1c 100644 --- a/bin/process-options.js +++ b/bin/process-options.js @@ -1,17 +1,19 @@ +"use strict"; + module.exports = function processOptions(yargs, argv) { // process Promise function ifArg(name, fn, init) { if(Array.isArray(argv[name])) { if(init) init(); argv[name].forEach(fn); - } else if(typeof argv[name] !== 'undefined') { + } else if(typeof argv[name] !== "undefined") { if(init) init(); fn(argv[name], -1); } } - var options = require('./convert-argv')(yargs, argv); + var options = require("./convert-argv")(yargs, argv); - if(typeof options.then === 'function') { + if(typeof options.then === "function") { options.then(processOptions).catch(function(err) { console.error(err.stack || err); process.exit(); @@ -21,111 +23,111 @@ module.exports = function processOptions(yargs, argv) { var firstOptions = Array.isArray(options) ? (options[0] || {}) : options; - if(typeof options.stats === 'boolean' || typeof options.stats === 'string') { - var statsPresetToOptions = require('webpack/lib/Stats.js').presetToOptions; + if(typeof options.stats === "boolean" || typeof options.stats === "string") { + var statsPresetToOptions = require("webpack/lib/Stats.js").presetToOptions; options.stats = statsPresetToOptions(options.stats); } var outputOptions = Object.create(options.stats || firstOptions.stats || {}); - if(typeof outputOptions.context === 'undefined') + if(typeof outputOptions.context === "undefined") outputOptions.context = firstOptions.context; - ifArg('json', function(bool) { + ifArg("json", function(bool) { if(bool) outputOptions.json = bool; }); - if(typeof outputOptions.colors === 'undefined') - outputOptions.colors = require('supports-color'); + if(typeof outputOptions.colors === "undefined") + outputOptions.colors = require("supports-color"); - ifArg('sort-modules-by', function(value) { + ifArg("sort-modules-by", function(value) { outputOptions.modulesSort = value; }); - ifArg('sort-chunks-by', function(value) { + ifArg("sort-chunks-by", function(value) { outputOptions.chunksSort = value; }); - ifArg('sort-assets-by', function(value) { + ifArg("sort-assets-by", function(value) { outputOptions.assetsSort = value; }); - ifArg('display-exclude', function(value) { + ifArg("display-exclude", function(value) { outputOptions.exclude = value; }); if(!outputOptions.json) { - if(typeof outputOptions.cached === 'undefined') + if(typeof outputOptions.cached === "undefined") outputOptions.cached = false; - if(typeof outputOptions.cachedAssets === 'undefined') + if(typeof outputOptions.cachedAssets === "undefined") outputOptions.cachedAssets = false; - ifArg('display-chunks', function(bool) { + ifArg("display-chunks", function(bool) { outputOptions.modules = !bool; outputOptions.chunks = bool; }); - ifArg('display-entrypoints', function(bool) { + ifArg("display-entrypoints", function(bool) { outputOptions.entrypoints = bool; }); - ifArg('display-reasons', function(bool) { + ifArg("display-reasons", function(bool) { outputOptions.reasons = bool; }); - ifArg('display-used-exports', function(bool) { + ifArg("display-used-exports", function(bool) { outputOptions.usedExports = bool; }); - ifArg('display-provided-exports', function(bool) { + ifArg("display-provided-exports", function(bool) { outputOptions.providedExports = bool; }); - ifArg('display-error-details', function(bool) { + ifArg("display-error-details", function(bool) { outputOptions.errorDetails = bool; }); - ifArg('display-origins', function(bool) { + ifArg("display-origins", function(bool) { outputOptions.chunkOrigins = bool; }); - ifArg('display-cached', function(bool) { + ifArg("display-cached", function(bool) { if(bool) outputOptions.cached = true; }); - ifArg('display-cached-assets', function(bool) { + ifArg("display-cached-assets", function(bool) { if(bool) outputOptions.cachedAssets = true; }); - if(!outputOptions.exclude && !argv['display-modules']) - outputOptions.exclude = ['node_modules', 'bower_components', 'jam', 'components']; + if(!outputOptions.exclude && !argv["display-modules"]) + outputOptions.exclude = ["node_modules", "bower_components", "jam", "components"]; } else { - if(typeof outputOptions.chunks === 'undefined') + if(typeof outputOptions.chunks === "undefined") outputOptions.chunks = true; - if(typeof outputOptions.entrypoints === 'undefined') + if(typeof outputOptions.entrypoints === "undefined") outputOptions.entrypoints = true; - if(typeof outputOptions.modules === 'undefined') + if(typeof outputOptions.modules === "undefined") outputOptions.modules = true; - if(typeof outputOptions.chunkModules === 'undefined') + if(typeof outputOptions.chunkModules === "undefined") outputOptions.chunkModules = true; - if(typeof outputOptions.reasons === 'undefined') + if(typeof outputOptions.reasons === "undefined") outputOptions.reasons = true; - if(typeof outputOptions.cached === 'undefined') + if(typeof outputOptions.cached === "undefined") outputOptions.cached = true; - if(typeof outputOptions.cachedAssets === 'undefined') + if(typeof outputOptions.cachedAssets === "undefined") outputOptions.cachedAssets = true; } - ifArg('hide-modules', function(bool) { + ifArg("hide-modules", function(bool) { if(bool) { outputOptions.modules = false; outputOptions.chunkModules = false; } }); - var webpack = require('webpack/lib/webpack.js'); + var webpack = require("webpack/lib/webpack.js"); Error.stackTraceLimit = 30; var lastHash = null; @@ -133,10 +135,10 @@ module.exports = function processOptions(yargs, argv) { try { compiler = webpack(options); } catch(e) { - var WebpackOptionsValidationError = require('webpack/lib/WebpackOptionsValidationError'); + var WebpackOptionsValidationError = require("webpack/lib/WebpackOptionsValidationError"); if(e instanceof WebpackOptionsValidationError) { if(argv.color) - console.error('\u001b[1m\u001b[31m' + e.message + '\u001b[39m\u001b[22m'); + console.error("\u001b[1m\u001b[31m" + e.message + "\u001b[39m\u001b[22m"); else console.error(e.message); process.exit(1); @@ -145,7 +147,7 @@ module.exports = function processOptions(yargs, argv) { } if(argv.progress) { - var ProgressPlugin = require('webpack/lib/ProgressPlugin'); + var ProgressPlugin = require("webpack/lib/ProgressPlugin"); compiler.apply(new ProgressPlugin({ profile: argv.profile })); @@ -163,15 +165,15 @@ module.exports = function processOptions(yargs, argv) { process.exit(1); } if(outputOptions.json) { - process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + '\n'); + process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + "\n"); } else if(stats.hash !== lastHash) { lastHash = stats.hash; - process.stdout.write( '\n' + new Date() + '\n' + '\n'); - process.stdout.write(stats.toString(outputOptions) + '\n'); + process.stdout.write("\n" + new Date() + "\n" + "\n"); + process.stdout.write(stats.toString(outputOptions) + "\n"); if(argv.s) lastHash = null; } if(!options.watch && stats.hasErrors()) { - process.on('exit', function() { + process.on("exit", function() { process.exit(2); }); } @@ -180,13 +182,13 @@ module.exports = function processOptions(yargs, argv) { var primaryOptions = !Array.isArray(options) ? options : options[0]; var watchOptions = primaryOptions.watchOptions || primaryOptions.watch || {}; if(watchOptions.stdin) { - process.stdin.on('end', function() { + process.stdin.on("end", function() { process.exit(0); }); process.stdin.resume(); } compiler.watch(watchOptions, compilerCallback); - console.log('\nWebpack is watching the files…\n'); + console.log("\nWebpack is watching the files…\n"); } else compiler.run(compilerCallback); diff --git a/bin/webpack.js b/bin/webpack.js index 1a5a67aac00..74c6c745125 100755 --- a/bin/webpack.js +++ b/bin/webpack.js @@ -1,18 +1,20 @@ #!/usr/bin/env node +"use strict"; + /* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -var path = require('path'); +var path = require("path"); // var fs = require('fs'); // Local version replace global one -process.title = 'webpack'; +process.title = "webpack"; try { - var localWebpack = require.resolve(path.join(process.cwd(), 'node_modules', 'webpack-cli', 'bin', 'webpack.js')); - if(localWebpack && path.relative(localWebpack, __filename) !== '') { + var localWebpack = require.resolve(path.join(process.cwd(), "node_modules", "webpack-cli", "bin", "webpack.js")); + if(localWebpack && path.relative(localWebpack, __filename) !== "") { return require(localWebpack); } } catch(e) { @@ -32,141 +34,141 @@ try { }); */ } -var yargs = require('yargs') - .usage('webpack-cli ' + require('../package.json').version + '\n' + - 'Usage: https://webpack.github.io/docs/cli.html\n' + - 'Usage without config file: webpack [] \n' + - 'Usage with config file: webpack'); +var yargs = require("yargs") + .usage("webpack-cli " + require("../package.json").version + "\n" + + "Usage: https://webpack.github.io/docs/cli.html\n" + + "Usage without config file: webpack [] \n" + + "Usage with config file: webpack"); -require('./config-yargs')(yargs); +require("./config-yargs")(yargs); -var DISPLAY_GROUP = 'Stats options:'; -var BASIC_GROUP = 'Basic options:'; +var DISPLAY_GROUP = "Stats options:"; +var BASIC_GROUP = "Basic options:"; yargs.options({ - 'json': { - type: 'boolean', - alias: 'j', - describe: 'Prints the result as JSON.' - }, - 'progress': { - type: 'boolean', - describe: 'Print compilation progress in percentage', + "json": { + type: "boolean", + alias: "j", + describe: "Prints the result as JSON." + }, + "progress": { + type: "boolean", + describe: "Print compilation progress in percentage", group: BASIC_GROUP }, - 'color': { - type: 'boolean', - alias: 'colors', + "color": { + type: "boolean", + alias: "colors", default: function supportsColor() { - return require('supports-color'); + return require("supports-color"); }, group: DISPLAY_GROUP, - describe: 'Enables/Disables colors on the console' + describe: "Enables/Disables colors on the console" }, - 'sort-modules-by': { - type: 'string', + "sort-modules-by": { + type: "string", group: DISPLAY_GROUP, - describe: 'Sorts the modules list by property in module' + describe: "Sorts the modules list by property in module" }, - 'sort-chunks-by': { - type: 'string', + "sort-chunks-by": { + type: "string", group: DISPLAY_GROUP, - describe: 'Sorts the chunks list by property in chunk' + describe: "Sorts the chunks list by property in chunk" }, - 'sort-assets-by': { - type: 'string', + "sort-assets-by": { + type: "string", group: DISPLAY_GROUP, - describe: 'Sorts the assets list by property in asset' + describe: "Sorts the assets list by property in asset" }, - 'hide-modules': { - type: 'boolean', + "hide-modules": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Hides info about modules' + describe: "Hides info about modules" }, - 'display-exclude': { - type: 'string', + "display-exclude": { + type: "string", group: DISPLAY_GROUP, - describe: 'Exclude modules in the output' + describe: "Exclude modules in the output" }, - 'display-modules': { - type: 'boolean', + "display-modules": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display even excluded modules in the output' + describe: "Display even excluded modules in the output" }, - 'display-chunks': { - type: 'boolean', + "display-chunks": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display chunks in the output' + describe: "Display chunks in the output" }, - 'display-entrypoints': { - type: 'boolean', + "display-entrypoints": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display entry points in the output' + describe: "Display entry points in the output" }, - 'display-origins': { - type: 'boolean', + "display-origins": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display origins of chunks in the output' + describe: "Display origins of chunks in the output" }, - 'display-cached': { - type: 'boolean', + "display-cached": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display also cached modules in the output' + describe: "Display also cached modules in the output" }, - 'display-cached-assets': { - type: 'boolean', + "display-cached-assets": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display also cached assets in the output' + describe: "Display also cached assets in the output" }, - 'display-reasons': { - type: 'boolean', + "display-reasons": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display reasons about module inclusion in the output' + describe: "Display reasons about module inclusion in the output" }, - 'display-used-exports': { - type: 'boolean', + "display-used-exports": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display information about used exports in modules (Tree Shaking)' + describe: "Display information about used exports in modules (Tree Shaking)" }, - 'display-provided-exports': { - type: 'boolean', + "display-provided-exports": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display information about exports provided from modules' + describe: "Display information about exports provided from modules" }, - 'display-error-details': { - type: 'boolean', + "display-error-details": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Display details about errors' + describe: "Display details about errors" }, - 'verbose': { - type: 'boolean', + "verbose": { + type: "boolean", group: DISPLAY_GROUP, - describe: 'Show more details' + describe: "Show more details" } }); var argv = yargs.argv; if(argv.verbose) { - argv['display-reasons'] = true; - argv['display-entrypoints'] = true; - argv['display-used-exports'] = true; - argv['display-provided-exports'] = true; - argv['display-error-details'] = true; - argv['display-modules'] = true; - argv['display-cached'] = true; - argv['display-cached-assets'] = true; + argv["display-reasons"] = true; + argv["display-entrypoints"] = true; + argv["display-used-exports"] = true; + argv["display-provided-exports"] = true; + argv["display-error-details"] = true; + argv["display-modules"] = true; + argv["display-cached"] = true; + argv["display-cached-assets"] = true; } if(argv.init) { - require('../lib/initialize')(argv._); + require("../lib/initialize")(argv._); } else if(argv.migrate) { const filePaths = argv._; - if (!filePaths.length) { - throw new Error('Please specify a path to your webpack config'); + if(!filePaths.length) { + throw new Error("Please specify a path to your webpack config"); } const inputConfigPath = path.resolve(process.cwd(), filePaths[0]); - require('../lib/migrate.js')(inputConfigPath, inputConfigPath); + require("../lib/migrate.js")(inputConfigPath, inputConfigPath); } else { - require('./process-options')(yargs,argv); + require("./process-options")(yargs, argv); } diff --git a/example/neo-webpack.config.js b/example/neo-webpack.config.js index 458a1fd7f48..64a413af786 100644 --- a/example/neo-webpack.config.js +++ b/example/neo-webpack.config.js @@ -1,20 +1,20 @@ -var path = require('path'); +var path = require("path"); module.exports = { - devtool: 'eval', + devtool: "eval", entry: [ - './src/index' + "./src/index" ], output: { - path: path.join(__dirname, 'dist'), - filename: 'index.js' + path: path.join(__dirname, "dist"), + filename: "index.js" }, module: { rules: [{ test: /\.js$/, - use: ['babel'], - include: path.join(__dirname, 'src') + use: ["babel"], + include: path.join(__dirname, "src") }] } }; diff --git a/example/webpack.config.js b/example/webpack.config.js index d0dd7933a45..9c0e898811b 100644 --- a/example/webpack.config.js +++ b/example/webpack.config.js @@ -1,20 +1,20 @@ -var path = require('path'); +var path = require("path"); module.exports = { - devtool: 'eval', + devtool: "eval", entry: [ - './src/index' + "./src/index" ], output: { - path: path.join(__dirname, 'dist'), - filename: 'index.js' + path: path.join(__dirname, "dist"), + filename: "index.js" }, module: { loaders: [{ test: /\.js$/, - loaders: ['babel'], - include: path.join(__dirname, 'src') + loaders: ["babel"], + include: path.join(__dirname, "src") }] } }; diff --git a/lib/creator/generators/adapter.js b/lib/creator/generators/adapter.js index ae95fc287eb..ad3d280ca95 100644 --- a/lib/creator/generators/adapter.js +++ b/lib/creator/generators/adapter.js @@ -1,10 +1,12 @@ -const inquirer = require('inquirer'); +"use strict"; + +const inquirer = require("inquirer"); // we can use rxJS here to validate the answers against a generator module.exports = class WebpackAdapter { prompt(questions, callback) { const promise = inquirer.prompt(questions); - promise.then(callback || function(){}); + promise.then(callback || function() {}); return promise; } }; diff --git a/lib/creator/generators/index.js b/lib/creator/generators/index.js index 726f4c34205..f8efa335c9a 100644 --- a/lib/creator/generators/index.js +++ b/lib/creator/generators/index.js @@ -1,6 +1,7 @@ -const Generator = require('yeoman-generator'); -const Input = require('webpack-addons').Input; +"use strict"; +const Generator = require("yeoman-generator"); +const Input = require("webpack-addons").Input; module.exports = class WebpackGenerator extends Generator { constructor(args, opts) { @@ -8,14 +9,15 @@ module.exports = class WebpackGenerator extends Generator { this.configuration = {}; } prompting() { - return this.prompt([Input('entry', 'What is the name of the entry point in your application?'), - Input('output', 'What is the name of the output directory in your application?')]).then( (answer) => { - this.configuration.webpackOptions = answer; - }); + return this.prompt([Input("entry", "What is the name of the entry point in your application?"), + Input("output", "What is the name of the output directory in your application?") + ]).then((answer) => { + this.configuration.webpackOptions = answer; + }); } config() {} childDependencies() { - this.configuration.childDependencies = ['webpack-addons-preact']; + this.configuration.childDependencies = ["webpack-addons-preact"]; } inject() {} diff --git a/lib/creator/index.js b/lib/creator/index.js index 7f8daf8cb71..0ff056689fd 100644 --- a/lib/creator/index.js +++ b/lib/creator/index.js @@ -1,20 +1,18 @@ -const validateSchema = require('./utils/validateSchema.js'); -const webpackOptionsSchema = require('./utils/webpackOptionsSchema.json'); -const WebpackOptionsValidationError = require('./utils/WebpackOptionsValidationError'); -const initTransform = require('./init-transform'); -const chalk = require('chalk'); +"use strict"; + +const initTransform = require("./init-transform"); /* -* @function creator -* -* Main function to build up a webpack configuration. -* Either throws an error if it doesn't match the webpack schema, -* or validates the filepaths of the options given. -* If a package is supplied, it finds the path of the package and runs inquirer -* -* @param { Array } pkgPaths - An Array of packages to run -* @param { } opts - An object containing webpackOptions or nothing -* @returns { } initTransform - Initializes the scaffold in yeoman -*/ + * @function creator + * + * Main function to build up a webpack configuration. + * Either throws an error if it doesn't match the webpack schema, + * or validates the filepaths of the options given. + * If a package is supplied, it finds the path of the package and runs inquirer + * + * @param { Array } pkgPaths - An Array of packages to run + * @param { } opts - An object containing webpackOptions or nothing + * @returns { } initTransform - Initializes the scaffold in yeoman + */ module.exports = function creator(pkgPaths, opts) { // null, config -> without package @@ -22,12 +20,10 @@ module.exports = function creator(pkgPaths, opts) { // we're dealing with init, we need to change this later, as it may have been emptied by yeoman if(!pkgPaths && !opts) { initTransform(); - } - else if(pkgPaths) { + } else if(pkgPaths) { // this example app actually needs a refactor in order for it to work initTransform(pkgPaths); - } - else if(!pkgPaths && opts) { + } else if(!pkgPaths && opts) { console.log(opts); // scaffold is done /* diff --git a/lib/creator/init-transform.js b/lib/creator/init-transform.js index d557cc2997e..aef50c3212c 100644 --- a/lib/creator/init-transform.js +++ b/lib/creator/init-transform.js @@ -1,37 +1,36 @@ -const fs = require('fs'); -const path = require('path'); -const yeoman = require('yeoman-environment'); -const Generator = require('yeoman-generator'); -const initGenerator = require('./generators/index'); -const WebpackAdapter = require('./generators/adapter'); +"use strict"; + +const yeoman = require("yeoman-environment"); +const initGenerator = require("./generators/index"); +const WebpackAdapter = require("./generators/adapter"); /* -* @function initTransform -* -* Runs yeoman and in the future lets us grab the answers from the generators -* -* @param { Array } options - An Array of paths to match generators for -* @returns { } -*/ + * @function initTransform + * + * Runs yeoman and in the future lets us grab the answers from the generators + * + * @param { Array } options - An Array of paths to match generators for + * @returns { } + */ module.exports = function initTransform(options) { - const creator = require('./index'); + const creator = require("./index"); const env = yeoman.createEnv(null, null, new WebpackAdapter()); if(options) { - env.register(require.resolve(options), 'npm:app'); + env.register(require.resolve(options), "npm:app"); - env.run('npm:app') - .on('end', () => { - return creator(null, env.getArgument('configuration')); - }); + env.run("npm:app") + .on("end", () => { + return creator(null, env.getArgument("configuration")); + }); } else { - env.registerStub(initGenerator, 'npm:app'); + env.registerStub(initGenerator, "npm:app"); - env.run('npm:app') - .on('end', () => { - return creator(null, env.getArgument('configuration')); - }); + env.run("npm:app") + .on("end", () => { + return creator(null, env.getArgument("configuration")); + }); } }; diff --git a/lib/creator/utils/WebpackOptionsValidationError.js b/lib/creator/utils/WebpackOptionsValidationError.js index 4fb7693faf3..ef496f135aa 100644 --- a/lib/creator/utils/WebpackOptionsValidationError.js +++ b/lib/creator/utils/WebpackOptionsValidationError.js @@ -2,16 +2,16 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Gajus Kuizinas @gajus */ -'use strict'; +"use strict"; -const webpackOptionsSchema = require('./webpackOptionsSchema.json'); +const webpackOptionsSchema = require("./webpackOptionsSchema.json"); const getSchemaPart = (path, parents, additionalPath) => { parents = parents || 0; - path = path.split('/'); + path = path.split("/"); path = path.slice(0, path.length - parents); if(additionalPath) { - additionalPath = additionalPath.split('/'); + additionalPath = additionalPath.split("/"); path = path.concat(additionalPath); } let schemaPart = webpackOptionsSchema; @@ -40,7 +40,7 @@ const getSchemaPartText = (schemaPart, additionalPath) => { const indent = (str, prefix, firstLine) => { if(firstLine) { - return prefix + str.replace(/\n(?!$)/g, '\n' + prefix); + return prefix + str.replace(/\n(?!$)/g, "\n" + prefix); } else { return str.replace(/\n(?!$)/g, `\n${prefix}`); } @@ -49,14 +49,14 @@ const indent = (str, prefix, firstLine) => { class WebpackOptionsValidationError extends Error { constructor(validationErrors) { super(); - if(Error.hasOwnProperty('captureStackTrace')) { + if(Error.hasOwnProperty("captureStackTrace")) { Error.captureStackTrace(this, this.constructor); } - this.name = 'WebpackOptionsValidationError'; + this.name = "WebpackOptionsValidationError"; - this.message = 'Invalid configuration object. ' + - 'Webpack has been initialised using a configuration object that does not match the API schema.\n' + - validationErrors.map(err => ' - ' + indent(WebpackOptionsValidationError.formatValidationError(err), ' ', false)).join('\n'); + this.message = "Invalid configuration object. " + + "Webpack has been initialised using a configuration object that does not match the API schema.\n" + + validationErrors.map(err => " - " + indent(WebpackOptionsValidationError.formatValidationError(err), " ", false)).join("\n"); this.validationErrors = validationErrors; } @@ -65,116 +65,116 @@ class WebpackOptionsValidationError extends Error { const formatInnerSchema = (innerSchema, addSelf) => { if(!addSelf) return WebpackOptionsValidationError.formatSchema(innerSchema, prevSchemas); - if(prevSchemas.indexOf(innerSchema) >= 0) return '(recursive)'; + if(prevSchemas.indexOf(innerSchema) >= 0) return "(recursive)"; return WebpackOptionsValidationError.formatSchema(innerSchema, prevSchemas.concat(schema)); }; - if(schema.type === 'string') { + if(schema.type === "string") { if(schema.minLength === 1) - return 'non-empty string'; + return "non-empty string"; else if(schema.minLength > 1) return `string (min length ${schema.minLength})`; - return 'string'; - } else if(schema.type === 'boolean') { - return 'boolean'; - } else if(schema.type === 'number') { - return 'number'; - } else if(schema.type === 'object') { + return "string"; + } else if(schema.type === "boolean") { + return "boolean"; + } else if(schema.type === "number") { + return "number"; + } else if(schema.type === "object") { if(schema.properties) { const required = schema.required || []; return `object { ${Object.keys(schema.properties).map(property => { - if(required.indexOf(property) < 0) return property + '?'; + if(required.indexOf(property) < 0) return property + "?"; return property; - }).concat(schema.additionalProperties ? ['...'] : []).join(', ')} }`; + }).concat(schema.additionalProperties ? ["..."] : []).join(", ")} }`; } if(schema.additionalProperties) { return `object { : ${formatInnerSchema(schema.additionalProperties)} }`; } - return 'object'; - } else if(schema.type === 'array') { + return "object"; + } else if(schema.type === "array") { return `[${formatInnerSchema(schema.items)}]`; } switch(schema.instanceof) { - case 'Function': - return 'function'; - case 'RegExp': - return 'RegExp'; + case "Function": + return "function"; + case "RegExp": + return "RegExp"; } if(schema.$ref) return formatInnerSchema(getSchemaPart(schema.$ref), true); - if(schema.allOf) return schema.allOf.map(formatInnerSchema).join(' & '); - if(schema.oneOf) return schema.oneOf.map(formatInnerSchema).join(' | '); - if(schema.anyOf) return schema.anyOf.map(formatInnerSchema).join(' | '); - if(schema.enum) return schema.enum.map(item => JSON.stringify(item)).join(' | '); + if(schema.allOf) return schema.allOf.map(formatInnerSchema).join(" & "); + if(schema.oneOf) return schema.oneOf.map(formatInnerSchema).join(" | "); + if(schema.anyOf) return schema.anyOf.map(formatInnerSchema).join(" | "); + if(schema.enum) return schema.enum.map(item => JSON.stringify(item)).join(" | "); return JSON.stringify(schema, 0, 2); } static formatValidationError(err) { const dataPath = `configuration${err.dataPath}`; - if(err.keyword === 'additionalProperties') { + if(err.keyword === "additionalProperties") { const baseMessage = `${dataPath} has an unknown property '${err.params.additionalProperty}'. These properties are valid:\n${getSchemaPartText(err.parentSchema)}`; if(!err.dataPath) { switch(err.params.additionalProperty) { - case 'debug': - return `${baseMessage}\n` + - 'The \'debug\' property was removed in webpack 2.\n' + - 'Loaders should be updated to allow passing this option via loader options in module.rules.\n' + - 'Until loaders are updated one can use the LoaderOptionsPlugin to switch loaders into debug mode:\n' + - 'plugins: [\n' + - ' new webpack.LoaderOptionsPlugin({\n' + - ' debug: true\n' + - ' })\n' + - ']'; + case "debug": + return `${baseMessage}\n` + + "The 'debug' property was removed in webpack 2.\n" + + "Loaders should be updated to allow passing this option via loader options in module.rules.\n" + + "Until loaders are updated one can use the LoaderOptionsPlugin to switch loaders into debug mode:\n" + + "plugins: [\n" + + " new webpack.LoaderOptionsPlugin({\n" + + " debug: true\n" + + " })\n" + + "]"; } - return baseMessage + '\n' + - 'For typos: please correct them.\n' + - 'For loader options: webpack 2 no longer allows custom properties in configuration.\n' + - ' Loaders should be updated to allow passing options via loader options in module.rules.\n' + - ' Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:\n' + - ' plugins: [\n' + - ' new webpack.LoaderOptionsPlugin({\n' + - ' // test: /\\.xxx$/, // may apply this only for some modules\n' + - ' options: {\n' + + return baseMessage + "\n" + + "For typos: please correct them.\n" + + "For loader options: webpack 2 no longer allows custom properties in configuration.\n" + + " Loaders should be updated to allow passing options via loader options in module.rules.\n" + + " Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:\n" + + " plugins: [\n" + + " new webpack.LoaderOptionsPlugin({\n" + + " // test: /\\.xxx$/, // may apply this only for some modules\n" + + " options: {\n" + ` ${err.params.additionalProperty}: ...\n` + - ' }\n' + - ' })\n' + - ' ]'; + " }\n" + + " })\n" + + " ]"; } return baseMessage; - } else if(err.keyword === 'oneOf' || err.keyword === 'anyOf') { + } else if(err.keyword === "oneOf" || err.keyword === "anyOf") { if(err.children && err.children.length > 0) { return `${dataPath} should be one of these:\n${getSchemaPartText(err.parentSchema)}\n` + - `Details:\n${err.children.map(err => ' * ' + indent(WebpackOptionsValidationError.formatValidationError(err), ' ', false)).join('\n')}`; + `Details:\n${err.children.map(err => " * " + indent(WebpackOptionsValidationError.formatValidationError(err), " ", false)).join("\n")}`; } return `${dataPath} should be one of these:\n${getSchemaPartText(err.parentSchema)}`; - } else if(err.keyword === 'enum') { + } else if(err.keyword === "enum") { if(err.parentSchema && err.parentSchema.enum && err.parentSchema.enum.length === 1) { return `${dataPath} should be ${getSchemaPartText(err.parentSchema)}`; } return `${dataPath} should be one of these:\n${getSchemaPartText(err.parentSchema)}`; - } else if(err.keyword === 'allOf') { + } else if(err.keyword === "allOf") { return `${dataPath} should be:\n${getSchemaPartText(err.parentSchema)}`; - } else if(err.keyword === 'type') { + } else if(err.keyword === "type") { switch(err.params.type) { - case 'object': - return `${dataPath} should be an object.`; - case 'string': - return `${dataPath} should be a string.`; - case 'boolean': - return `${dataPath} should be a boolean.`; - case 'number': - return `${dataPath} should be a number.`; - case 'array': - return `${dataPath} should be an array:\n${getSchemaPartText(err.parentSchema)}`; + case "object": + return `${dataPath} should be an object.`; + case "string": + return `${dataPath} should be a string.`; + case "boolean": + return `${dataPath} should be a boolean.`; + case "number": + return `${dataPath} should be a number.`; + case "array": + return `${dataPath} should be an array:\n${getSchemaPartText(err.parentSchema)}`; } return `${dataPath} should be ${err.params.type}:\n${getSchemaPartText(err.parentSchema)}`; - } else if(err.keyword === 'instanceof') { + } else if(err.keyword === "instanceof") { return `${dataPath} should be an instance of ${getSchemaPartText(err.parentSchema)}.`; - } else if(err.keyword === 'required') { - const missingProperty = err.params.missingProperty.replace(/^\./, ''); - return `${dataPath} misses the property '${missingProperty}'.\n${getSchemaPartText(err.parentSchema, ['properties', missingProperty])}`; - } else if(err.keyword === 'minLength' || err.keyword === 'minItems') { + } else if(err.keyword === "required") { + const missingProperty = err.params.missingProperty.replace(/^\./, ""); + return `${dataPath} misses the property '${missingProperty}'.\n${getSchemaPartText(err.parentSchema, ["properties", missingProperty])}`; + } else if(err.keyword === "minLength" || err.keyword === "minItems") { if(err.params.limit === 1) return `${dataPath} should not be empty.`; else diff --git a/lib/creator/utils/validateSchema.js b/lib/creator/utils/validateSchema.js index c6360de2367..a23942d1c05 100644 --- a/lib/creator/utils/validateSchema.js +++ b/lib/creator/utils/validateSchema.js @@ -2,7 +2,7 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Gajus Kuizinas @gajus */ -'use strict'; +"use strict"; /* eslint-disable */ const Ajv = require('ajv'); diff --git a/lib/creator/validate-options.js b/lib/creator/validate-options.js index be76787e0f8..fa5d6ecdda9 100644 --- a/lib/creator/validate-options.js +++ b/lib/creator/validate-options.js @@ -1,36 +1,38 @@ -const fs = require('fs'); -const path = require('path'); +"use strict"; + +const fs = require("fs"); +const path = require("path"); /* -* @function getPath -* -* Finds the current filepath of a given string -* -* @param { String } part - The name of the file to be checked. -* @returns { String } - returns an string with the filepath -*/ + * @function getPath + * + * Finds the current filepath of a given string + * + * @param { String } part - The name of the file to be checked. + * @returns { String } - returns an string with the filepath + */ function getPath(part) { return path.join(process.cwd(), part); } /* -* @function validateOptions -* -* Validates the options passed from an inquirer instance to make -* sure the path supplied exists -* -* @param { String } part - The name of the file to be checked. -* @returns { } part - checks if the path exists or throws an error -*/ + * @function validateOptions + * + * Validates the options passed from an inquirer instance to make + * sure the path supplied exists + * + * @param { String } part - The name of the file to be checked. + * @returns { } part - checks if the path exists or throws an error + */ module.exports = function validateOptions(opts) { - return Object.keys(opts).forEach( (location) => { + return Object.keys(opts).forEach((location) => { let part = getPath(opts[location]); try { fs.readFileSync(part); - } catch (err) { - console.error('Found no file at:', part); + } catch(err) { + console.error("Found no file at:", part); process.exit(1); } }); diff --git a/lib/creator/validate-options.spec.js b/lib/creator/validate-options.spec.js index 5ffa642da2a..129203a4646 100644 --- a/lib/creator/validate-options.spec.js +++ b/lib/creator/validate-options.spec.js @@ -1,19 +1,24 @@ -'use strict'; +"use strict"; -const validateOptions = require('../../__mocks__/creator/validate-options.mock').validateOptions; +const validateOptions = require("../../__mocks__/creator/validate-options.mock").validateOptions; -describe('validate-options', () => { +describe("validate-options", () => { - it('should throw on fake paths', () => { + it("should throw on fake paths", () => { expect(() => { - validateOptions({entry: 'noop', output: 'noopsi'}); - }).toThrowError('Did not find the file'); + validateOptions({ + entry: "noop", + output: "noopsi" + }); + }).toThrowError("Did not find the file"); }); - it('should find the real files', () => { + it("should find the real files", () => { expect(() => { - validateOptions({entry: 'package.json'}); - }).not.toThrowError('Did not find the file'); + validateOptions({ + entry: "package.json" + }); + }).not.toThrowError("Did not find the file"); }); }); diff --git a/lib/initialize.js b/lib/initialize.js index 81a107ff32b..e4b2d594ee6 100644 --- a/lib/initialize.js +++ b/lib/initialize.js @@ -1,19 +1,21 @@ -const npmPackagesExists = require('./utils/npm-packages-exists'); -const creator = require('./creator/index'); +"use strict"; + +const npmPackagesExists = require("./utils/npm-packages-exists"); +const creator = require("./creator/index"); /* -* @function initializeInquirer -* -* First function to be called after running the init flag. This is a check, -* if we are running the init command with no arguments or if we got dependencies -* -* @param { Object } pkg - packages included when running the init command -* @returns { } prompt|npmPackagesExists - returns either an inquirer prompt with -* the initial questions we provide, or validates the packages given -*/ + * @function initializeInquirer + * + * First function to be called after running the init flag. This is a check, + * if we are running the init command with no arguments or if we got dependencies + * + * @param { Object } pkg - packages included when running the init command + * @returns { } prompt|npmPackagesExists - returns either an inquirer prompt with + * the initial questions we provide, or validates the packages given + */ module.exports = function initializeInquirer(pkg) { - if(pkg.length == 0) { + if(pkg.length === 0) { return creator(); } return npmPackagesExists(pkg); diff --git a/lib/migrate.js b/lib/migrate.js index 797afe1258c..ba7c0d0efbd 100644 --- a/lib/migrate.js +++ b/lib/migrate.js @@ -1,46 +1,47 @@ -const fs = require('fs'); -const chalk = require('chalk'); -const diff = require('diff'); -const inquirer = require('inquirer'); -const PLazy = require('p-lazy'); -const Listr = require('listr'); +"use strict"; + +const fs = require("fs"); +const chalk = require("chalk"); +const diff = require("diff"); +const inquirer = require("inquirer"); +const PLazy = require("p-lazy"); +const Listr = require("listr"); module.exports = function transformFile(currentConfigPath, outputConfigPath, options) { const recastOptions = Object.assign({ - quote: 'single' + quote: "single" }, options); - const tasks = new Listr([ - { - title: 'Reading webpack config', - task: (ctx) => new PLazy((resolve, reject) => { - fs.readFile(currentConfigPath, 'utf8', (err, content) => { - if (err) { - reject(err); - } - try { - const jscodeshift = require('jscodeshift'); - ctx.source = content; - ctx.ast = jscodeshift(content); - resolve(); - } catch (err) { - reject('Error generating AST', err); - } - }); - }) - }, - { - title: 'Migrating config from v1 to v2', - task: (ctx) => { - const transformations = require('./transformations').transformations; - return new Listr(Object.keys(transformations).map(key => { - const transform = transformations[key]; - return { - title: key, - task: () => transform(ctx.ast, ctx.source) - }; - })); - } + const tasks = new Listr([{ + title: "Reading webpack config", + task: (ctx) => new PLazy((resolve, reject) => { + fs.readFile(currentConfigPath, "utf8", (err, content) => { + if(err) { + reject(err); + } + try { + const jscodeshift = require("jscodeshift"); + ctx.source = content; + ctx.ast = jscodeshift(content); + resolve(); + } catch(err) { + reject("Error generating AST", err); + } + }); + }) + }, + { + title: "Migrating config from v1 to v2", + task: (ctx) => { + const transformations = require("./transformations").transformations; + return new Listr(Object.keys(transformations).map(key => { + const transform = transformations[key]; + return { + title: key, + task: () => transform(ctx.ast, ctx.source) + }; + })); } + } ]); tasks.run() @@ -48,33 +49,31 @@ module.exports = function transformFile(currentConfigPath, outputConfigPath, opt const result = ctx.ast.toSource(recastOptions); const diffOutput = diff.diffLines(ctx.source, result); diffOutput.forEach(diffLine => { - if (diffLine.added) { + if(diffLine.added) { process.stdout.write(chalk.green(`+ ${diffLine.value}`)); - } else if (diffLine.removed) { + } else if(diffLine.removed) { process.stdout.write(chalk.red(`- ${diffLine.value}`)); } }); inquirer - .prompt([ - { - type: 'confirm', - name: 'confirmMigration', - message: 'Are you sure these changes are fine?', - default: 'Y' - } - ]) + .prompt([{ + type: "confirm", + name: "confirmMigration", + message: "Are you sure these changes are fine?", + default: "Y" + }]) .then(answers => { - if (answers['confirmMigration']) { + if(answers["confirmMigration"]) { // TODO validate the config - fs.writeFileSync(outputConfigPath, result, 'utf8'); + fs.writeFileSync(outputConfigPath, result, "utf8"); console.log(chalk.green(`✔︎ New webpack v2 config file is at ${outputConfigPath}`)); } else { - console.log(chalk.red('✖ Migration aborted')); + console.log(chalk.red("✖ Migration aborted")); } }); }) .catch(err => { - console.log(chalk.red('✖ ︎Migration aborted due to some errors')); + console.log(chalk.red("✖ ︎Migration aborted due to some errors")); console.error(err); process.exitCode = 1; }); diff --git a/lib/transformations/bannerPlugin/bannerPlugin.js b/lib/transformations/bannerPlugin/bannerPlugin.js index 9f40d172f7d..5c2f29148eb 100644 --- a/lib/transformations/bannerPlugin/bannerPlugin.js +++ b/lib/transformations/bannerPlugin/bannerPlugin.js @@ -1,19 +1,20 @@ -const utils = require('../utils'); +"use strict"; + +const utils = require("../utils"); module.exports = function(j, ast) { - return utils.findPluginsByName(j, ast, ['webpack.BannerPlugin']) + return utils.findPluginsByName(j, ast, ["webpack.BannerPlugin"]) .forEach(path => { const args = path.value.arguments; // If the first argument is a literal replace it with object notation // See https://webpack.js.org/guides/migrating/#bannerplugin-breaking-change - if (args && args.length > 1 && args[0].type === j.Literal.name) { + if(args && args.length > 1 && args[0].type === j.Literal.name) { // and remove the first argument path.value.arguments = [path.value.arguments[1]]; - utils.createOrUpdatePluginByName(j, path.parent, 'webpack.BannerPlugin', { + utils.createOrUpdatePluginByName(j, path.parent, "webpack.BannerPlugin", { banner: args[0].value }); } }); - }; diff --git a/lib/transformations/bannerPlugin/bannerPlugin.test.js b/lib/transformations/bannerPlugin/bannerPlugin.test.js index fee919e427e..004d08b6635 100644 --- a/lib/transformations/bannerPlugin/bannerPlugin.test.js +++ b/lib/transformations/bannerPlugin/bannerPlugin.test.js @@ -1,5 +1,7 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'bannerPlugin', 'bannerPlugin-0'); -defineTest(__dirname, 'bannerPlugin', 'bannerPlugin-1'); -defineTest(__dirname, 'bannerPlugin', 'bannerPlugin-2'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "bannerPlugin", "bannerPlugin-0"); +defineTest(__dirname, "bannerPlugin", "bannerPlugin-1"); +defineTest(__dirname, "bannerPlugin", "bannerPlugin-2"); diff --git a/lib/transformations/defineTest.js b/lib/transformations/defineTest.js index 36a1017765e..e44996e69b1 100644 --- a/lib/transformations/defineTest.js +++ b/lib/transformations/defineTest.js @@ -1,7 +1,8 @@ -'use strict'; +/* eslint-disable valid-jsdoc */ +"use strict"; -const fs = require('fs'); -const path = require('path'); +const fs = require("fs"); +const path = require("path"); /** * Utility function to run a jscodeshift script within a unit test. This makes @@ -23,26 +24,28 @@ const path = require('path'); * alongside the transform and __tests__ directory. */ function runSingleTansform(dirName, transformName, testFilePrefix) { - if (!testFilePrefix) { + if(!testFilePrefix) { testFilePrefix = transformName; } - const fixtureDir = path.join(dirName, '__testfixtures__'); - const inputPath = path.join(fixtureDir, testFilePrefix + '.input.js'); - const source = fs.readFileSync(inputPath, 'utf8'); + const fixtureDir = path.join(dirName, "__testfixtures__"); + const inputPath = path.join(fixtureDir, testFilePrefix + ".input.js"); + const source = fs.readFileSync(inputPath, "utf8"); // Assumes transform and test are on the same level - const module = require(path.join(dirName, transformName + '.js')); + const module = require(path.join(dirName, transformName + ".js")); // Handle ES6 modules using default export for the transform const transform = module.default ? module.default : module; // Jest resets the module registry after each test, so we need to always get // a fresh copy of jscodeshift on every test run. - let jscodeshift = require('jscodeshift/dist/core'); - if (module.parser) { + let jscodeshift = require("jscodeshift/dist/core"); + if(module.parser) { jscodeshift = jscodeshift.withParser(module.parser); } const ast = jscodeshift(source); - return transform(jscodeshift, ast, source).toSource({ quote: 'single' }); + return transform(jscodeshift, ast, source).toSource({ + quote: "single" + }); } /** @@ -50,9 +53,9 @@ function runSingleTansform(dirName, transformName, testFilePrefix) { * jscodeshift transform. */ function defineTest(dirName, transformName, testFilePrefix) { - const testName = testFilePrefix - ? `transforms correctly using "${testFilePrefix}" data` - : 'transforms correctly'; + const testName = testFilePrefix ? + `transforms correctly using "${testFilePrefix}" data` : + "transforms correctly"; describe(transformName, () => { it(testName, () => { const output = runSingleTansform(dirName, transformName, testFilePrefix); diff --git a/lib/transformations/extractTextPlugin/extractTextPlugin.js b/lib/transformations/extractTextPlugin/extractTextPlugin.js index 3d60fedffdb..55539d7c968 100644 --- a/lib/transformations/extractTextPlugin/extractTextPlugin.js +++ b/lib/transformations/extractTextPlugin/extractTextPlugin.js @@ -1,9 +1,11 @@ -const utils = require('../utils'); +"use strict"; + +const utils = require("../utils"); function findInvocation(j, node, pluginName) { return j(node) .find(j.MemberExpression) - .filter(p => p.get('object').value.name === pluginName).size() > 0; + .filter(p => p.get("object").value.name === pluginName).size() > 0; } module.exports = function(j, ast) { @@ -12,21 +14,19 @@ module.exports = function(j, ast) { // if(args.length === 1) { // return p; // } else - const literalArgs = args.filter(p => utils.isType(p, 'Literal')); - if (literalArgs && literalArgs.length > 1) { + const literalArgs = args.filter(p => utils.isType(p, "Literal")); + if(literalArgs && literalArgs.length > 1) { const newArgs = j.objectExpression(literalArgs.map((p, index) => - utils.createProperty(j, index === 0 ? 'fallback': 'use', p.value) + utils.createProperty(j, index === 0 ? "fallback" : "use", p.value) )); p.value.arguments = [newArgs]; } return p; }; - const name = utils.findVariableToPlugin(j, ast, 'extract-text-webpack-plugin'); + const name = utils.findVariableToPlugin(j, ast, "extract-text-webpack-plugin"); if(!name) return ast; return ast.find(j.CallExpression) .filter(p => findInvocation(j, p, name)) - .forEach(changeArguments); + .forEach(changeArguments); }; - - diff --git a/lib/transformations/extractTextPlugin/extractTextPlugin.test.js b/lib/transformations/extractTextPlugin/extractTextPlugin.test.js index 66d74802356..199067becf3 100644 --- a/lib/transformations/extractTextPlugin/extractTextPlugin.test.js +++ b/lib/transformations/extractTextPlugin/extractTextPlugin.test.js @@ -1,3 +1,5 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'extractTextPlugin'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "extractTextPlugin"); diff --git a/lib/transformations/index.js b/lib/transformations/index.js index 721b66612f5..15366430695 100644 --- a/lib/transformations/index.js +++ b/lib/transformations/index.js @@ -1,15 +1,17 @@ -const jscodeshift = require('jscodeshift'); -const pEachSeries = require('p-each-series'); -const PLazy = require('p-lazy'); +"use strict"; -const loadersTransform = require('./loaders/loaders'); -const resolveTransform = require('./resolve/resolve'); -const removeJsonLoaderTransform = require('./removeJsonLoader/removeJsonLoader'); -const uglifyJsPluginTransform = require('./uglifyJsPlugin/uglifyJsPlugin'); -const loaderOptionsPluginTransform = require('./loaderOptionsPlugin/loaderOptionsPlugin'); -const bannerPluginTransform = require('./bannerPlugin/bannerPlugin'); -const extractTextPluginTransform = require('./extractTextPlugin/extractTextPlugin'); -const removeDeprecatedPluginsTransform = require('./removeDeprecatedPlugins/removeDeprecatedPlugins'); +const jscodeshift = require("jscodeshift"); +const pEachSeries = require("p-each-series"); +const PLazy = require("p-lazy"); + +const loadersTransform = require("./loaders/loaders"); +const resolveTransform = require("./resolve/resolve"); +const removeJsonLoaderTransform = require("./removeJsonLoader/removeJsonLoader"); +const uglifyJsPluginTransform = require("./uglifyJsPlugin/uglifyJsPlugin"); +const loaderOptionsPluginTransform = require("./loaderOptionsPlugin/loaderOptionsPlugin"); +const bannerPluginTransform = require("./bannerPlugin/bannerPlugin"); +const extractTextPluginTransform = require("./extractTextPlugin/extractTextPlugin"); +const removeDeprecatedPluginsTransform = require("./removeDeprecatedPlugins/removeDeprecatedPlugins"); const transformsObject = { loadersTransform, @@ -32,7 +34,7 @@ function transformSingleAST(ast, source, transformFunction) { setTimeout(() => { try { resolve(transformFunction(jscodeshift, ast, source)); - } catch (err) { + } catch(err) { reject(err); } }, 0); @@ -53,7 +55,7 @@ function transformSingleAST(ast, source, transformFunction) { function transform(source, transforms, options) { const ast = jscodeshift(source); const recastOptions = Object.assign({ - quote: 'single' + quote: "single" }, options); transforms = transforms || Object.keys(transformations).map(k => transformations[k]); return pEachSeries(transforms, f => f(ast, source)) diff --git a/lib/transformations/index.test.js b/lib/transformations/index.test.js index 4953beb8640..ed74dcf8609 100644 --- a/lib/transformations/index.test.js +++ b/lib/transformations/index.test.js @@ -1,5 +1,7 @@ -const transform = require('./index').transform; -const transformations = require('./index').transformations; +"use strict"; + +const transform = require("./index").transform; +const transformations = require("./index").transformations; const input = ` module.exports = { @@ -30,31 +32,31 @@ module.exports = { }; `; -describe('transform', () => { - it('should not transform if no transformations defined', (done) => { +describe("transform", () => { + it("should not transform if no transformations defined", (done) => { transform(input, []).then(output => { expect(output).toEqual(input); done(); }); }); - it('should transform using all transformations', (done) => { + it("should transform using all transformations", (done) => { transform(input).then(output => { expect(output).toMatchSnapshot(); done(); }); }); - it('should transform only using specified transformations', (done) => { + it("should transform only using specified transformations", (done) => { transform(input, [transformations.loadersTransform]).then(output => { expect(output).toMatchSnapshot(); done(); }); }); - it('should respect recast options', (done) => { + it("should respect recast options", (done) => { transform(input, undefined, { - quote: 'double', + quote: "double", trailingComma: true }).then(output => { expect(output).toMatchSnapshot(); diff --git a/lib/transformations/loaderOptionsPlugin/loaderOptionsPlugin.js b/lib/transformations/loaderOptionsPlugin/loaderOptionsPlugin.js index d959c4f56e0..2706f0acbe9 100644 --- a/lib/transformations/loaderOptionsPlugin/loaderOptionsPlugin.js +++ b/lib/transformations/loaderOptionsPlugin/loaderOptionsPlugin.js @@ -1,7 +1,9 @@ -const isEmpty = require('lodash/isEmpty'); -const findPluginsByName = require('../utils').findPluginsByName; -const createOrUpdatePluginByName = require('../utils').createOrUpdatePluginByName; -const safeTraverse = require('../utils').safeTraverse; +"use strict"; + +const isEmpty = require("lodash/isEmpty"); +const findPluginsByName = require("../utils").findPluginsByName; +const createOrUpdatePluginByName = require("../utils").createOrUpdatePluginByName; +const safeTraverse = require("../utils").safeTraverse; module.exports = function(j, ast) { const loaderOptions = {}; @@ -9,20 +11,22 @@ module.exports = function(j, ast) { // If there is debug: true, set debug: true in the plugin // TODO: remove global debug setting // TODO: I can't figure out how to find the topmost `debug: true`. help! - if (ast.find(j.Identifier, { name: 'debug' }).size()) { + if(ast.find(j.Identifier, { + name: "debug" + }).size()) { loaderOptions.debug = true; } // If there is UglifyJsPlugin, set minimize: true - if (findPluginsByName(j, ast, ['webpack.optimize.UglifyJsPlugin']).size()) { + if(findPluginsByName(j, ast, ["webpack.optimize.UglifyJsPlugin"]).size()) { loaderOptions.minimize = true; } return ast .find(j.ArrayExpression) - .filter(path => safeTraverse(path, ['parent', 'value', 'key', 'name']) === 'plugins') + .filter(path => safeTraverse(path, ["parent", "value", "key", "name"]) === "plugins") .forEach(path => { !isEmpty(loaderOptions) && - createOrUpdatePluginByName(j, path, 'webpack.optimize.LoaderOptionsPlugin', loaderOptions); + createOrUpdatePluginByName(j, path, "webpack.optimize.LoaderOptionsPlugin", loaderOptions); }); }; diff --git a/lib/transformations/loaderOptionsPlugin/loaderOptionsPlugin.test.js b/lib/transformations/loaderOptionsPlugin/loaderOptionsPlugin.test.js index 1339fc4bf35..bb3c78de07c 100644 --- a/lib/transformations/loaderOptionsPlugin/loaderOptionsPlugin.test.js +++ b/lib/transformations/loaderOptionsPlugin/loaderOptionsPlugin.test.js @@ -1,6 +1,8 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'loaderOptionsPlugin', 'loaderOptionsPlugin-0'); -defineTest(__dirname, 'loaderOptionsPlugin', 'loaderOptionsPlugin-1'); -defineTest(__dirname, 'loaderOptionsPlugin', 'loaderOptionsPlugin-2'); -defineTest(__dirname, 'loaderOptionsPlugin', 'loaderOptionsPlugin-3'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "loaderOptionsPlugin", "loaderOptionsPlugin-0"); +defineTest(__dirname, "loaderOptionsPlugin", "loaderOptionsPlugin-1"); +defineTest(__dirname, "loaderOptionsPlugin", "loaderOptionsPlugin-2"); +defineTest(__dirname, "loaderOptionsPlugin", "loaderOptionsPlugin-3"); diff --git a/lib/transformations/loaders/loaders.js b/lib/transformations/loaders/loaders.js index 2bb15f17a24..b515d1aa6af 100644 --- a/lib/transformations/loaders/loaders.js +++ b/lib/transformations/loaders/loaders.js @@ -1,11 +1,13 @@ -const utils = require('../utils'); +"use strict"; + +const utils = require("../utils"); module.exports = function(j, ast) { const createArrayExpression = function(p) { - let objs = p.parent.node.value.value.split('!') + let objs = p.parent.node.value.value.split("!") .map(val => j.objectExpression([ - utils.createProperty(j, 'loader', val) + utils.createProperty(j, "loader", val) ])); let loaderArray = j.arrayExpression(objs); p.parent.node.value = loaderArray; @@ -15,108 +17,106 @@ module.exports = function(j, ast) { const createLoaderWithQuery = p => { let properties = p.value.properties; let loaderValue = properties - .reduce((val, prop) => prop.key.name === 'loader' ? prop.value.value : val, ''); - let loader = loaderValue.split('?')[0]; - let query = loaderValue.split('?')[1]; - let options = query.split('&').map(option => { - const param = option.split('='); + .reduce((val, prop) => prop.key.name === "loader" ? prop.value.value : val, ""); + let loader = loaderValue.split("?")[0]; + let query = loaderValue.split("?")[1]; + let options = query.split("&").map(option => { + const param = option.split("="); const key = param[0]; const val = param[1] || true; // No value in query string means it is truthy value return j.objectProperty(j.identifier(key), utils.createLiteral(val)); }); - let loaderProp = utils.createProperty(j, 'loader', loader); - let queryProp = j.property('init', j.identifier('options'), j.objectExpression(options)); + let loaderProp = utils.createProperty(j, "loader", loader); + let queryProp = j.property("init", j.identifier("options"), j.objectExpression(options)); return j.objectExpression([loaderProp, queryProp]); }; const findLoaderWithQueryString = p => { return p.value.properties .reduce((predicate, prop) => { - return utils.safeTraverse(prop, ['value', 'value', 'indexOf']) - && prop.value.value.indexOf('?') > -1 - || predicate; + return utils.safeTraverse(prop, ["value", "value", "indexOf"]) && + prop.value.value.indexOf("?") > -1 || + predicate; }, false); }; - const checkForLoader = p => p.value.name === 'loaders' && utils.safeTraverse(p, - ['parent', 'parent', 'parent', 'node', 'key', 'name']) === 'module'; + const checkForLoader = p => p.value.name === "loaders" && utils.safeTraverse(p, ["parent", "parent", "parent", "node", "key", "name"]) === "module"; const fitIntoLoaders = p => { let loaders; p.value.properties.map(prop => { const keyName = prop.key.name; - if (keyName === 'loaders') { + if(keyName === "loaders") { loaders = prop.value; } }); p.value.properties.map(prop => { const keyName = prop.key.name; - if (keyName !== 'loaders') { - const enforceVal = keyName === 'preLoaders' ? 'pre' : 'post'; + if(keyName !== "loaders") { + const enforceVal = keyName === "preLoaders" ? "pre" : "post"; prop.value.elements.map(elem => { - elem.properties.push(utils.createProperty(j, 'enforce', enforceVal)); - if (loaders && loaders.type === 'ArrayExpression') { + elem.properties.push(utils.createProperty(j, "enforce", enforceVal)); + if(loaders && loaders.type === "ArrayExpression") { loaders.elements.push(elem); } else { - prop.key.name = 'loaders'; + prop.key.name = "loaders"; } }); } }); - if (loaders) { - p.value.properties = p.value.properties.filter(prop => prop.key.name === 'loaders'); + if(loaders) { + p.value.properties = p.value.properties.filter(prop => prop.key.name === "loaders"); } return p; }; const prepostLoaders = () => ast .find(j.ObjectExpression) - .filter(p => utils.findObjWithOneOfKeys(p, ['preLoaders', 'postLoaders'])) + .filter(p => utils.findObjWithOneOfKeys(p, ["preLoaders", "postLoaders"])) .forEach(p => p = fitIntoLoaders(p)); const loadersToRules = () => ast .find(j.Identifier) .filter(checkForLoader) - .forEach(p => p.value.name = 'rules'); + .forEach(p => p.value.name = "rules"); const loaderToUse = () => ast .find(j.Identifier) .filter(p => { - return (p.value.name === 'loaders' || p.value.name === 'loader') - && utils.safeTraverse(p, - ['parent', 'parent', 'parent', 'parent', 'node', 'key', 'name']) === 'rules'; + return (p.value.name === "loaders" || p.value.name === "loader") && + utils.safeTraverse(p, ["parent", "parent", "parent", "parent", "node", "key", "name"]) === "rules"; }) - .forEach(p => p.value.name = 'use'); + .forEach(p => p.value.name = "use"); const loadersInArray = () => ast .find(j.Identifier) .filter(p => { - return p.value.name === 'use' - && p.parent.node.value.type === 'Literal' - && p.parent.node.value.value.indexOf('!') > 0; + return p.value.name === "use" && + p.parent.node.value.type === "Literal" && + p.parent.node.value.value.indexOf("!") > 0; }) .forEach(createArrayExpression); const loaderWithQueryParam = () => ast .find(j.ObjectExpression) - .filter(p => utils.findObjWithOneOfKeys(p, 'loader')) + .filter(p => utils.findObjWithOneOfKeys(p, "loader")) .filter(findLoaderWithQueryString) .replaceWith(createLoaderWithQuery); const loaderWithQueryProp = () => ast .find(j.Identifier) - .filter(p => p.value.name === 'query') - .replaceWith(j.identifier('options')); + .filter(p => p.value.name === "query") + .replaceWith(j.identifier("options")); const addLoaderSuffix = () => ast .find(j.ObjectExpression) .forEach(path => { path.value.properties.forEach(prop => { - if ((prop.key.name === 'loader' || prop.key.name === 'use') - && utils.safeTraverse(prop, ['value', 'value']) - && prop.value.value.indexOf('-loader') === -1) { - prop.value = j.literal(prop.value.value + '-loader'); + if((prop.key.name === "loader" || prop.key.name === "use") && + utils.safeTraverse(prop, ["value", "value"]) && + prop.value.value.indexOf("-loader") === -1) { + prop.value = j.literal(prop.value.value + "-loader"); } }); }) diff --git a/lib/transformations/loaders/loaders.test.js b/lib/transformations/loaders/loaders.test.js index 3e77665cbe2..dfc037cbba4 100644 --- a/lib/transformations/loaders/loaders.test.js +++ b/lib/transformations/loaders/loaders.test.js @@ -1,9 +1,11 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'loaders', 'loaders-0'); -defineTest(__dirname, 'loaders', 'loaders-1'); -defineTest(__dirname, 'loaders', 'loaders-2'); -defineTest(__dirname, 'loaders', 'loaders-3'); -defineTest(__dirname, 'loaders', 'loaders-4'); -defineTest(__dirname, 'loaders', 'loaders-5'); -defineTest(__dirname, 'loaders', 'loaders-6'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "loaders", "loaders-0"); +defineTest(__dirname, "loaders", "loaders-1"); +defineTest(__dirname, "loaders", "loaders-2"); +defineTest(__dirname, "loaders", "loaders-3"); +defineTest(__dirname, "loaders", "loaders-4"); +defineTest(__dirname, "loaders", "loaders-5"); +defineTest(__dirname, "loaders", "loaders-6"); diff --git a/lib/transformations/outputPath/outputPath.js b/lib/transformations/outputPath/outputPath.js index 78226dc345f..8778bd3c0b8 100644 --- a/lib/transformations/outputPath/outputPath.js +++ b/lib/transformations/outputPath/outputPath.js @@ -1,28 +1,30 @@ -const utils = require('../utils'); +"use strict"; + +const utils = require("../utils"); module.exports = function(j, ast) { const literalOutputPath = ast .find(j.ObjectExpression) - .filter(p => utils.safeTraverse(p, ['parentPath', 'value', 'key', 'name']) === 'output') + .filter(p => utils.safeTraverse(p, ["parentPath", "value", "key", "name"]) === "output") .find(j.Property) - .filter(p => utils.safeTraverse(p, ['value', 'key', 'name']) === 'path' - && utils.safeTraverse(p, ['value', 'value', 'type']) === 'Literal'); + .filter(p => utils.safeTraverse(p, ["value", "key", "name"]) === "path" && + utils.safeTraverse(p, ["value", "value", "type"]) === "Literal"); - if (literalOutputPath) { - let pathVarName = 'path'; + if(literalOutputPath) { + let pathVarName = "path"; let isPathPresent = false; const pathDecalaration = ast .find(j.VariableDeclarator) - .filter(p => utils.safeTraverse(p, ['value', 'init', 'callee', 'name']) === 'require') - .filter(p => utils.safeTraverse(p, ['value', 'init', 'arguments']) - && p.value.init.arguments.reduce((isPresent, a) => { - return a.type === 'Literal' && a.value === 'path' || isPresent; - }, false)); + .filter(p => utils.safeTraverse(p, ["value", "init", "callee", "name"]) === "require") + .filter(p => utils.safeTraverse(p, ["value", "init", "arguments"]) && + p.value.init.arguments.reduce((isPresent, a) => { + return a.type === "Literal" && a.value === "path" || isPresent; + }, false)); - if (pathDecalaration) { + if(pathDecalaration) { isPathPresent = true; pathDecalaration.forEach(p => { - pathVarName = utils.safeTraverse(p, ['value', 'id', 'name']); + pathVarName = utils.safeTraverse(p, ["value", "id", "name"]); }); } @@ -30,8 +32,8 @@ module.exports = function(j, ast) { .find(j.Literal) .replaceWith(p => replaceWithPath(j, p, pathVarName)); - if(!isPathPresent){ - const pathRequire = utils.getRequire(j, 'path', 'path'); + if(!isPathPresent) { + const pathRequire = utils.getRequire(j, "path", "path"); return ast.find(j.Program) .replaceWith(p => j.program([].concat(pathRequire).concat(p.value.body))); } @@ -42,10 +44,8 @@ module.exports = function(j, ast) { function replaceWithPath(j, p, pathVarName) { const convertedPath = j.callExpression( j.memberExpression( - j.identifier(pathVarName), - j.identifier('join'), - false), - [j.identifier('__dirname'), p.value]); + j.identifier(pathVarName), + j.identifier("join"), + false), [j.identifier("__dirname"), p.value]); return convertedPath; } - diff --git a/lib/transformations/outputPath/outputPath.test.js b/lib/transformations/outputPath/outputPath.test.js index d1041b30274..1312905c074 100644 --- a/lib/transformations/outputPath/outputPath.test.js +++ b/lib/transformations/outputPath/outputPath.test.js @@ -1,5 +1,7 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'outputPath', 'outputPath-0'); -defineTest(__dirname, 'outputPath', 'outputPath-1'); -defineTest(__dirname, 'outputPath', 'outputPath-2'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "outputPath", "outputPath-0"); +defineTest(__dirname, "outputPath", "outputPath-1"); +defineTest(__dirname, "outputPath", "outputPath-2"); diff --git a/lib/transformations/removeDeprecatedPlugins/removeDeprecatedPlugins.js b/lib/transformations/removeDeprecatedPlugins/removeDeprecatedPlugins.js index a3d193800f3..ad3beb8b9d5 100644 --- a/lib/transformations/removeDeprecatedPlugins/removeDeprecatedPlugins.js +++ b/lib/transformations/removeDeprecatedPlugins/removeDeprecatedPlugins.js @@ -1,6 +1,8 @@ -const codeFrame = require('babel-code-frame'); -const chalk = require('chalk'); -const utils = require('../utils'); +"use strict"; + +const codeFrame = require("babel-code-frame"); +const chalk = require("chalk"); +const utils = require("../utils"); const example = `plugins: [ new webpack.optimize.OccurrenceOrderPlugin(), @@ -12,19 +14,19 @@ module.exports = function(j, ast, source) { // List of deprecated plugins to remove // each item refers to webpack.optimize.[NAME] construct const deprecatedPlugingsList = [ - 'webpack.optimize.OccurrenceOrderPlugin', - 'webpack.optimize.DedupePlugin' + "webpack.optimize.OccurrenceOrderPlugin", + "webpack.optimize.DedupePlugin" ]; return utils.findPluginsByName(j, ast, deprecatedPlugingsList) .forEach(path => { // For now we only support the case there plugins are defined in an Array - const arrayPath = utils.safeTraverse(path, ['parent','value']); - if (arrayPath && utils.isType(arrayPath, 'ArrayExpression')) { + const arrayPath = utils.safeTraverse(path, ["parent", "value"]); + if(arrayPath && utils.isType(arrayPath, "ArrayExpression")) { // Check how many plugins are defined and // if there is only last plugin left remove `plugins: []` node - const arrayElementsPath = utils.safeTraverse(arrayPath, ['elements']); - if (arrayElementsPath && arrayElementsPath.length === 1) { + const arrayElementsPath = utils.safeTraverse(arrayPath, ["elements"]); + if(arrayElementsPath && arrayElementsPath.length === 1) { j(path.parent.parent).remove(); } else { j(path).remove(); @@ -32,16 +34,16 @@ module.exports = function(j, ast, source) { } else { const startLoc = path.value.loc.start; console.log(` -${ chalk.red('Only plugins instantiated in the array can be automatically removed i.e.:') } +${ chalk.red("Only plugins instantiated in the array can be automatically removed i.e.:") } ${ codeFrame(example, null, null, { highlightCode: true }) } -${ chalk.red('but you use it like this:') } +${ chalk.red("but you use it like this:") } ${ codeFrame(source, startLoc.line, startLoc.column, { highlightCode: true }) } -${ chalk.red('Please remove deprecated plugins manually. ') } -See ${ chalk.underline('https://webpack.js.org/guides/migrating/')} for more information.`); +${ chalk.red("Please remove deprecated plugins manually. ") } +See ${ chalk.underline("https://webpack.js.org/guides/migrating/")} for more information.`); } }); }; diff --git a/lib/transformations/removeDeprecatedPlugins/removeDeprecatedPlugins.test.js b/lib/transformations/removeDeprecatedPlugins/removeDeprecatedPlugins.test.js index 748a0c35ea1..e029dff487d 100644 --- a/lib/transformations/removeDeprecatedPlugins/removeDeprecatedPlugins.test.js +++ b/lib/transformations/removeDeprecatedPlugins/removeDeprecatedPlugins.test.js @@ -1,7 +1,9 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'removeDeprecatedPlugins', 'removeDeprecatedPlugins-0'); -defineTest(__dirname, 'removeDeprecatedPlugins', 'removeDeprecatedPlugins-1'); -defineTest(__dirname, 'removeDeprecatedPlugins', 'removeDeprecatedPlugins-2'); -defineTest(__dirname, 'removeDeprecatedPlugins', 'removeDeprecatedPlugins-3'); -defineTest(__dirname, 'removeDeprecatedPlugins', 'removeDeprecatedPlugins-4'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "removeDeprecatedPlugins", "removeDeprecatedPlugins-0"); +defineTest(__dirname, "removeDeprecatedPlugins", "removeDeprecatedPlugins-1"); +defineTest(__dirname, "removeDeprecatedPlugins", "removeDeprecatedPlugins-2"); +defineTest(__dirname, "removeDeprecatedPlugins", "removeDeprecatedPlugins-3"); +defineTest(__dirname, "removeDeprecatedPlugins", "removeDeprecatedPlugins-4"); diff --git a/lib/transformations/removeJsonLoader/removeJsonLoader.js b/lib/transformations/removeJsonLoader/removeJsonLoader.js index 0b7bcbac56f..2806b8cb9bf 100644 --- a/lib/transformations/removeJsonLoader/removeJsonLoader.js +++ b/lib/transformations/removeJsonLoader/removeJsonLoader.js @@ -1,41 +1,49 @@ +"use strict"; + module.exports = function(j, ast) { function getLoadersPropertyPaths(ast) { - return ast.find(j.Property, { key: { name: 'use' } }); + return ast.find(j.Property, { + key: { + name: "use" + } + }); } function removeLoaderByName(path, name) { const loadersNode = path.value.value; - switch (loadersNode.type) { - case j.ArrayExpression.name: { - let loaders = loadersNode.elements.map(p => p.value); - const loaderIndex = loaders.indexOf(name); - if (loaders.length && loaderIndex > -1) { - // Remove loader from the array - loaders.splice(loaderIndex, 1); - // and from AST - loadersNode.elements.splice(loaderIndex, 1); - } + switch(loadersNode.type) { + case j.ArrayExpression.name: + { + let loaders = loadersNode.elements.map(p => p.value); + const loaderIndex = loaders.indexOf(name); + if(loaders.length && loaderIndex > -1) { + // Remove loader from the array + loaders.splice(loaderIndex, 1); + // and from AST + loadersNode.elements.splice(loaderIndex, 1); + } - // If there is only one element left, convert to string - if (loaders.length === 1) { - j(path.get('value')).replaceWith(j.literal(loaders[0])); - } - break; - } - case j.Literal.name: { - // If only the loader with the matching name was used - // we can remove the whole Property node completely - if (loadersNode.value === name) { - j(path.parent).remove(); - } - break; - } + // If there is only one element left, convert to string + if(loaders.length === 1) { + j(path.get("value")).replaceWith(j.literal(loaders[0])); + } + break; + } + case j.Literal.name: + { + // If only the loader with the matching name was used + // we can remove the whole Property node completely + if(loadersNode.value === name) { + j(path.parent).remove(); + } + break; + } } } function removeLoaders(ast) { getLoadersPropertyPaths(ast) - .forEach(path => removeLoaderByName(path, 'json-loader')); + .forEach(path => removeLoaderByName(path, "json-loader")); } const transforms = [ diff --git a/lib/transformations/removeJsonLoader/removeJsonLoader.test.js b/lib/transformations/removeJsonLoader/removeJsonLoader.test.js index 164f0045ee1..a448e68bf02 100644 --- a/lib/transformations/removeJsonLoader/removeJsonLoader.test.js +++ b/lib/transformations/removeJsonLoader/removeJsonLoader.test.js @@ -1,6 +1,8 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'removeJsonLoader', 'removeJsonLoader-0'); -defineTest(__dirname, 'removeJsonLoader', 'removeJsonLoader-1'); -defineTest(__dirname, 'removeJsonLoader', 'removeJsonLoader-2'); -defineTest(__dirname, 'removeJsonLoader', 'removeJsonLoader-3'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "removeJsonLoader", "removeJsonLoader-0"); +defineTest(__dirname, "removeJsonLoader", "removeJsonLoader-1"); +defineTest(__dirname, "removeJsonLoader", "removeJsonLoader-2"); +defineTest(__dirname, "removeJsonLoader", "removeJsonLoader-3"); diff --git a/lib/transformations/resolve/resolve.js b/lib/transformations/resolve/resolve.js index 3912703e9e0..97262b39ade 100644 --- a/lib/transformations/resolve/resolve.js +++ b/lib/transformations/resolve/resolve.js @@ -1,33 +1,35 @@ +"use strict"; + module.exports = function transformer(j, ast) { const getRootVal = p => { - return p.node.value.properties.filter(prop => prop.key.name === 'root')[0]; + return p.node.value.properties.filter(prop => prop.key.name === "root")[0]; }; const getRootIndex = p => { return p.node.value.properties .reduce((rootIndex, prop, index) => { - return prop.key.name === 'root' ? index : rootIndex; + return prop.key.name === "root" ? index : rootIndex; }, -1); }; const isModulePresent = p => { - const modules = p.node.value.properties.filter(prop => prop.key.name === 'modules'); + const modules = p.node.value.properties.filter(prop => prop.key.name === "modules"); return modules.length > 0 && modules[0]; }; const createModuleArray = p => { const rootVal = getRootVal(p); let modulesVal = null; - if (rootVal.value.type === 'ArrayExpression') { + if(rootVal.value.type === "ArrayExpression") { modulesVal = rootVal.value.elements; } else { modulesVal = [rootVal.value]; } let module = isModulePresent(p); - if (!module) { - module = j.property('init', j.identifier('modules'), j.arrayExpression(modulesVal)); + if(!module) { + module = j.property("init", j.identifier("modules"), j.arrayExpression(modulesVal)); p.node.value.properties = p.node.value.properties.concat([module]); } else { module.value.elements = module.value.elements.concat(modulesVal); @@ -40,10 +42,10 @@ module.exports = function transformer(j, ast) { return ast .find(j.Property) .filter(p => { - return p.node.key.name === 'resolve' - && p.node.value.properties - .filter(prop => prop.key.name === 'root') - .length === 1; + return p.node.key.name === "resolve" && + p.node.value.properties + .filter(prop => prop.key.name === "root") + .length === 1; }) .forEach(createModuleArray); }; diff --git a/lib/transformations/resolve/resolve.test.js b/lib/transformations/resolve/resolve.test.js index 30a26b5348b..9cbd9d22957 100644 --- a/lib/transformations/resolve/resolve.test.js +++ b/lib/transformations/resolve/resolve.test.js @@ -1,3 +1,5 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'resolve'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "resolve"); diff --git a/lib/transformations/uglifyJsPlugin/uglifyJsPlugin.js b/lib/transformations/uglifyJsPlugin/uglifyJsPlugin.js index f5c4a12af3b..e2820b0e76f 100644 --- a/lib/transformations/uglifyJsPlugin/uglifyJsPlugin.js +++ b/lib/transformations/uglifyJsPlugin/uglifyJsPlugin.js @@ -1,20 +1,22 @@ -const findPluginsByName = require('../utils').findPluginsByName; +"use strict"; + +const findPluginsByName = require("../utils").findPluginsByName; module.exports = function(j, ast) { function createSourceMapsProperty() { - return j.property('init', j.identifier('sourceMap'), j.identifier('true')); + return j.property("init", j.identifier("sourceMap"), j.identifier("true")); } - return findPluginsByName(j, ast, ['webpack.optimize.UglifyJsPlugin']) + return findPluginsByName(j, ast, ["webpack.optimize.UglifyJsPlugin"]) .forEach(path => { const args = path.value.arguments; - if (args.length) { + if(args.length) { // Plugin is called with object as arguments j(path) .find(j.ObjectExpression) - .get('properties') + .get("properties") .value .push(createSourceMapsProperty()); } else { diff --git a/lib/transformations/uglifyJsPlugin/uglifyJsPlugin.test.js b/lib/transformations/uglifyJsPlugin/uglifyJsPlugin.test.js index a0c309ccb1e..4b43262cbdc 100644 --- a/lib/transformations/uglifyJsPlugin/uglifyJsPlugin.test.js +++ b/lib/transformations/uglifyJsPlugin/uglifyJsPlugin.test.js @@ -1,5 +1,7 @@ -const defineTest = require('../defineTest'); +"use strict"; -defineTest(__dirname, 'uglifyJsPlugin', 'uglifyJsPlugin-0'); -defineTest(__dirname, 'uglifyJsPlugin', 'uglifyJsPlugin-1'); -defineTest(__dirname, 'uglifyJsPlugin', 'uglifyJsPlugin-2'); +const defineTest = require("../defineTest"); + +defineTest(__dirname, "uglifyJsPlugin", "uglifyJsPlugin-0"); +defineTest(__dirname, "uglifyJsPlugin", "uglifyJsPlugin-1"); +defineTest(__dirname, "uglifyJsPlugin", "uglifyJsPlugin-2"); diff --git a/lib/transformations/utils.js b/lib/transformations/utils.js index 428d0e315ee..82a433f2dbb 100644 --- a/lib/transformations/utils.js +++ b/lib/transformations/utils.js @@ -1,9 +1,11 @@ +"use strict"; + function safeTraverse(obj, paths) { let val = obj; let idx = 0; - while (idx < paths.length) { - if (!val) { + while(idx < paths.length) { + if(!val) { return null; } val = val[paths[idx]]; @@ -14,17 +16,17 @@ function safeTraverse(obj, paths) { // Convert nested MemberExpressions to strings like webpack.optimize.DedupePlugin function memberExpressionToPathString(path) { - if (path && path.object) { - return [memberExpressionToPathString(path.object), path.property.name].join('.'); + if(path && path.object) { + return [memberExpressionToPathString(path.object), path.property.name].join("."); } return path.name; } // Convert Array like ['webpack', 'optimize', 'DedupePlugin'] to nested MemberExpressions function pathsToMemberExpression(j, paths) { - if (!paths.length) { + if(!paths.length) { return null; - } else if (paths.length === 1) { + } else if(paths.length === 1) { return j.identifier(paths[0]); } else { const first = paths.slice(0, 1); @@ -37,21 +39,21 @@ function pathsToMemberExpression(j, paths) { } /* -* @function findPluginsByName -* -* Find paths that match `new name.space.PluginName()` for a given array of plugin names -* -* @param j — jscodeshift API -* @param { Node } node - Node to start search from -* @param { Array } pluginNamesArray - Array of plugin names like `webpack.optimize.LoaderOptionsPlugin` -* @returns Path + * @function findPluginsByName + * + * Find paths that match `new name.space.PluginName()` for a given array of plugin names + * + * @param j — jscodeshift API + * @param { Node } node - Node to start search from + * @param { Array } pluginNamesArray - Array of plugin names like `webpack.optimize.LoaderOptionsPlugin` + * @returns Path * */ function findPluginsByName(j, node, pluginNamesArray) { return node .find(j.NewExpression) .filter(path => { return pluginNamesArray.some( - plugin => memberExpressionToPathString(path.get('callee').value) === plugin + plugin => memberExpressionToPathString(path.get("callee").value) === plugin ); }); } @@ -66,7 +68,11 @@ function findPluginsByName(j, node, pluginNamesArray) { * @returns Path * */ function findPluginsRootNodes(j, node) { - return node.find(j.Property, { key: { name: 'plugins' } }); + return node.find(j.Property, { + key: { + name: "plugins" + } + }); } /* @@ -81,7 +87,7 @@ function findPluginsRootNodes(j, node) { * */ function createProperty(j, key, value) { return j.property( - 'init', + "init", createLiteral(j, key), createLiteral(j, value) ); @@ -100,13 +106,13 @@ function createProperty(j, key, value) { function createLiteral(j, val) { let literalVal = val; // We'll need String to native type conversions - if (typeof val === 'string') { + if(typeof val === "string") { // 'true' => true - if (val === 'true') literalVal = true; + if(val === "true") literalVal = true; // 'false' => false - if (val === 'false') literalVal = false; + if(val === "false") literalVal = false; // '1' => 1 - if (!isNaN(Number(val))) literalVal = Number(val); + if(!isNaN(Number(val))) literalVal = Number(val); } return j.literal(literalVal); } @@ -126,24 +132,24 @@ function createLiteral(j, val) { function createOrUpdatePluginByName(j, rootNodePath, pluginName, options) { const pluginInstancePath = findPluginsByName(j, j(rootNodePath), [pluginName]); let optionsProps; - if (options) { + if(options) { optionsProps = Object.keys(options).map(key => { return createProperty(j, key, options[key]); }); } // If plugin declaration already exist - if (pluginInstancePath.size()) { + if(pluginInstancePath.size()) { pluginInstancePath.forEach(path => { // There are options we want to pass as argument - if (optionsProps) { + if(optionsProps) { const args = path.value.arguments; - if (args.length) { + if(args.length) { // Plugin is called with object as arguments // we will merge those objects let currentProps = j(path) .find(j.ObjectExpression) - .get('properties'); + .get("properties"); optionsProps.forEach(opt => { // Search for same keys in the existing object @@ -151,7 +157,7 @@ function createOrUpdatePluginByName(j, rootNodePath, pluginName, options) { .find(j.Identifier) .filter(path => opt.key.value === path.value.name); - if (existingProps.size()) { + if(existingProps.size()) { // Replacing values for the same key existingProps.forEach(path => { j(path.parent).replaceWith(opt); @@ -172,11 +178,11 @@ function createOrUpdatePluginByName(j, rootNodePath, pluginName, options) { }); } else { let argumentsArray = []; - if (optionsProps) { + if(optionsProps) { argumentsArray = [j.objectExpression(optionsProps)]; } const loaderPluginInstance = j.newExpression( - pathsToMemberExpression(j, pluginName.split('.').reverse()), + pathsToMemberExpression(j, pluginName.split(".").reverse()), argumentsArray ); rootNodePath.value.elements.push(loaderPluginInstance); @@ -194,55 +200,54 @@ function createOrUpdatePluginByName(j, rootNodePath, pluginName, options) { * @returns { string } variable name - ex. 'var s = require(s) gives "s"` * */ -function findVariableToPlugin(j, rootNode, pluginPackageName){ +function findVariableToPlugin(j, rootNode, pluginPackageName) { const moduleVarNames = rootNode.find(j.VariableDeclarator) .filter(j.filters.VariableDeclarator.requiresModule(pluginPackageName)) .nodes(); - if (moduleVarNames.length === 0) return null; + if(moduleVarNames.length === 0) return null; return moduleVarNames.pop().id.name; } /* -* @function isType -* -* Returns true if type is given type -* @param { Node} path - pathNode -* @param { string } type - node type -* @returns {boolean} -*/ + * @function isType + * + * Returns true if type is given type + * @param { Node} path - pathNode + * @param { string } type - node type + * @returns {boolean} + */ function isType(path, type) { return path.type === type; } -function findObjWithOneOfKeys (p, keyNames) { +function findObjWithOneOfKeys(p, keyNames) { return p.value.properties .reduce((predicate, prop) => { const name = prop.key.name; - return keyNames.indexOf(name) > -1 - || predicate; + return keyNames.indexOf(name) > -1 || + predicate; }, false); } /* -* @function getRequire -* -* Returns constructed require symbol -* @param j — jscodeshift API -* @param { string } constName - Name of require -* @param { string } packagePath - path of required package -* @returns {NodePath} - the created ast -*/ + * @function getRequire + * + * Returns constructed require symbol + * @param j — jscodeshift API + * @param { string } constName - Name of require + * @param { string } packagePath - path of required package + * @returns {NodePath} - the created ast + */ function getRequire(j, constName, packagePath) { - return j.variableDeclaration('const', [ + return j.variableDeclaration("const", [ j.variableDeclarator( - j.identifier(constName), - j.callExpression( - j.identifier('require'), - [j.literal(packagePath)] - ) - ) + j.identifier(constName), + j.callExpression( + j.identifier("require"), [j.literal(packagePath)] + ) + ) ]); } diff --git a/lib/transformations/utils.test.js b/lib/transformations/utils.test.js index 73a8c93a9fc..83768b6aa91 100644 --- a/lib/transformations/utils.test.js +++ b/lib/transformations/utils.test.js @@ -1,68 +1,67 @@ -const j = require('jscodeshift/dist/core'); -const utils = require('./utils'); +"use strict"; -describe('utils', () => { - describe('createProperty', () => { - it('should create properties for Boolean', () => { - const res = utils.createProperty(j, 'foo', true); +const j = require("jscodeshift/dist/core"); +const utils = require("./utils"); + +describe("utils", () => { + describe("createProperty", () => { + it("should create properties for Boolean", () => { + const res = utils.createProperty(j, "foo", true); expect(j(j.objectExpression([res])).toSource()).toMatchSnapshot(); }); - it('should create properties for Number', () => { - const res = utils.createProperty(j, 'foo', -1); + it("should create properties for Number", () => { + const res = utils.createProperty(j, "foo", -1); expect(j(j.objectExpression([res])).toSource()).toMatchSnapshot(); }); - it('should create properties for String', () => { - const res = utils.createProperty(j, 'foo', 'bar'); + it("should create properties for String", () => { + const res = utils.createProperty(j, "foo", "bar"); expect(j(j.objectExpression([res])).toSource()).toMatchSnapshot(); }); - it('should create properties for complex keys', () => { - const res = utils.createProperty(j, 'foo-bar', 'bar'); + it("should create properties for complex keys", () => { + const res = utils.createProperty(j, "foo-bar", "bar"); expect(j(j.objectExpression([res])).toSource()).toMatchSnapshot(); }); - it('should create properties for non-literal keys', () => { - const res = utils.createProperty(j, 1, 'bar'); + it("should create properties for non-literal keys", () => { + const res = utils.createProperty(j, 1, "bar"); expect(j(j.objectExpression([res])).toSource()).toMatchSnapshot(); }); }); - describe('findPluginsByName', () => { - it('should find plugins in AST', () => { + describe("findPluginsByName", () => { + it("should find plugins in AST", () => { const ast = j(` { foo: new webpack.optimize.UglifyJsPlugin() } `); - const res = utils.findPluginsByName(j, ast, - ['webpack.optimize.UglifyJsPlugin']); + const res = utils.findPluginsByName(j, ast, ["webpack.optimize.UglifyJsPlugin"]); expect(res.size()).toEqual(1); }); - it('should find all plugins in AST', () => { + it("should find all plugins in AST", () => { const ast = j(` [ new UglifyJsPlugin(), new TestPlugin() ] `); - const res = utils.findPluginsByName(j, ast, - ['UglifyJsPlugin', 'TestPlugin']); + const res = utils.findPluginsByName(j, ast, ["UglifyJsPlugin", "TestPlugin"]); expect(res.size()).toEqual(2); }); - it('should not find false positives', () => { + it("should not find false positives", () => { const ast = j(` { foo: new UglifyJsPlugin() } `); - const res = utils.findPluginsByName(j, ast, - ['webpack.optimize.UglifyJsPlugin']); + const res = utils.findPluginsByName(j, ast, ["webpack.optimize.UglifyJsPlugin"]); expect(res.size()).toEqual(0); }); }); - describe('findPluginsRootNodes', () => { - it('should find plugins: [] nodes', () => { + describe("findPluginsRootNodes", () => { + it("should find plugins: [] nodes", () => { const ast = j(` var a = { plugins: [], foo: { plugins: [] } } `); @@ -70,7 +69,7 @@ var a = { plugins: [], foo: { plugins: [] } } expect(res.size()).toEqual(2); }); - it('should not find plugins: [] nodes', () => { + it("should not find plugins: [] nodes", () => { const ast = j(` var a = { plugs: [] } `); @@ -79,74 +78,83 @@ var a = { plugs: [] } }); }); - describe('createOrUpdatePluginByName', () => { - it('should create a new plugin without arguments', () => { - const ast = j('{ plugins: [] }'); + describe("createOrUpdatePluginByName", () => { + it("should create a new plugin without arguments", () => { + const ast = j("{ plugins: [] }"); ast .find(j.ArrayExpression) .forEach(node => { - utils.createOrUpdatePluginByName(j, node, 'Plugin'); + utils.createOrUpdatePluginByName(j, node, "Plugin"); }); expect(ast.toSource()).toMatchSnapshot(); }); - it('should create a new plugin with arguments', () => { - const ast = j('{ plugins: [] }'); + it("should create a new plugin with arguments", () => { + const ast = j("{ plugins: [] }"); ast .find(j.ArrayExpression) .forEach(node => { - utils.createOrUpdatePluginByName(j, node, 'Plugin', { foo: 'bar' }); + utils.createOrUpdatePluginByName(j, node, "Plugin", { + foo: "bar" + }); }); expect(ast.toSource()).toMatchSnapshot(); }); - it('should add an object as an argument', () => { - const ast = j('[new Plugin()]'); + it("should add an object as an argument", () => { + const ast = j("[new Plugin()]"); ast .find(j.ArrayExpression) .forEach(node => { - utils.createOrUpdatePluginByName(j, node, 'Plugin', { foo: true }); + utils.createOrUpdatePluginByName(j, node, "Plugin", { + foo: true + }); }); expect(ast.toSource()).toMatchSnapshot(); }); - it('should merge options objects', () => { - const ast = j('[new Plugin({ foo: true })]'); + it("should merge options objects", () => { + const ast = j("[new Plugin({ foo: true })]"); ast .find(j.ArrayExpression) .forEach(node => { - utils.createOrUpdatePluginByName(j, node, 'Plugin', { bar: 'baz', foo: false }); - utils.createOrUpdatePluginByName(j, node, 'Plugin', { 'baz-long': true }); + utils.createOrUpdatePluginByName(j, node, "Plugin", { + bar: "baz", + foo: false + }); + utils.createOrUpdatePluginByName(j, node, "Plugin", { + "baz-long": true + }); }); expect(ast.toSource()).toMatchSnapshot(); }); }); - describe('findVariableToPlugin', () => { - it('should find the variable name of a plugin', () => { + describe("findVariableToPlugin", () => { + it("should find the variable name of a plugin", () => { const ast = j(` var packageName = require('package-name'); var someOtherVar = somethingElse; var otherPackage = require('other-package'); `); - const foundVar = utils.findVariableToPlugin(j, ast, 'other-package'); - expect(foundVar).toEqual('otherPackage'); + const foundVar = utils.findVariableToPlugin(j, ast, "other-package"); + expect(foundVar).toEqual("otherPackage"); }); }); - describe('createLiteral', () => { - it('should create basic literal', () => { - const literal = utils.createLiteral(j, 'stringLiteral'); + describe("createLiteral", () => { + it("should create basic literal", () => { + const literal = utils.createLiteral(j, "stringLiteral"); expect(j(literal).toSource()).toMatchSnapshot(); }); - it('should create boolean', () => { - const literal = utils.createLiteral(j, 'true'); + it("should create boolean", () => { + const literal = utils.createLiteral(j, "true"); expect(j(literal).toSource()).toMatchSnapshot(); }); }); - describe('findObjWithOneOfKeys', () => { - it('should find keys', () => { + describe("findObjWithOneOfKeys", () => { + it("should find keys", () => { const ast = j(` var ab = { a: 1, @@ -154,13 +162,13 @@ var a = { plugs: [] } } `); expect(ast.find(j.ObjectExpression) - .filter(p => utils.findObjWithOneOfKeys(p, ['a'])).size()).toEqual(1); + .filter(p => utils.findObjWithOneOfKeys(p, ["a"])).size()).toEqual(1); }); }); - describe('getRequire', () => { - it('should create a require statement', () => { - const require = utils.getRequire(j, 'filesys', 'fs'); + describe("getRequire", () => { + it("should create a require statement", () => { + const require = utils.getRequire(j, "filesys", "fs"); expect(j(require).toSource()).toMatchSnapshot(); }); }); diff --git a/lib/utils/npm-exists.js b/lib/utils/npm-exists.js index 85dbb1345dd..902ef091bc3 100644 --- a/lib/utils/npm-exists.js +++ b/lib/utils/npm-exists.js @@ -1,26 +1,30 @@ -const got = require('got'); -const chalk = require('chalk'); +"use strict"; + +const got = require("got"); +const chalk = require("chalk"); const constant = value => () => value; /* -* @function npmExists -* -* Checks if the given dependency/module is registered on npm -* -* @param { String } moduleName - The dependency to be checked -* @returns { } constant - Returns either true or false, -* based on if it exists or not -*/ + * @function npmExists + * + * Checks if the given dependency/module is registered on npm + * + * @param { String } moduleName - The dependency to be checked + * @returns { } constant - Returns either true or false, + * based on if it exists or not + */ module.exports = function npmExists(moduleName) { //eslint-disable-next-line - if (moduleName.length <= 14 || moduleName.slice(0,14) !== 'webpack-addons') { + if(moduleName.length <= 14 ||  moduleName.slice(0, 14) !== 'webpack-addons') { throw new TypeError(chalk.bold(`${moduleName} isn\'t a valid name.\n`) + - chalk.red('\nIt should be prefixed with \'webpack-addons\', but have different suffix.\n')); + chalk.red("\nIt should be prefixed with 'webpack-addons', but have different suffix.\n")); } - const hostname = 'https://www.npmjs.org'; + const hostname = "https://www.npmjs.org"; const pkgUrl = `${hostname}/package/${moduleName}`; - return got(pkgUrl, {method: 'HEAD'}) + return got(pkgUrl, { + method: "HEAD" + }) .then(constant(true)) .catch(constant(false)); }; diff --git a/lib/utils/npm-exists.spec.js b/lib/utils/npm-exists.spec.js index b192127a4be..65935358bcf 100644 --- a/lib/utils/npm-exists.spec.js +++ b/lib/utils/npm-exists.spec.js @@ -1,16 +1,16 @@ /* eslint node/no-unsupported-features: 0 */ -'use strict'; -const exists = require('./npm-exists'); +"use strict"; +const exists = require("./npm-exists"); -describe('exists', () => { +describe("exists", () => { - it('should sucessfully existence of a published module', async () => { - let itExists = await exists('webpack-addons-ylvis'); + it("should sucessfully existence of a published module", async() => { + let itExists = await exists("webpack-addons-ylvis"); expect(itExists).toBe(true); }); - it('should return false for the existence of a fake module', async () => { - let itExists = await exists('webpack-addons-noop'); + it("should return false for the existence of a fake module", async() => { + let itExists = await exists("webpack-addons-noop"); expect(itExists).toBe(false); }); }); diff --git a/lib/utils/npm-packages-exists.js b/lib/utils/npm-packages-exists.js index 8748b1e47ac..d2be6183a05 100644 --- a/lib/utils/npm-packages-exists.js +++ b/lib/utils/npm-packages-exists.js @@ -1,37 +1,38 @@ -const npmExists = require('./npm-exists'); -const resolvePackages = require('./resolve-packages'); +"use strict"; +const npmExists = require("./npm-exists"); +const resolvePackages = require("./resolve-packages"); /* -* @function npmPackagesExists -* -* Loops through an array and checks if a package is registered -* on npm and throws an error if it is not from @checkEachPackage -* -* @param { Array } pkg - Array of packages to check existence of -* @returns { Array } resolvePackages - Returns an process to install the pkg -*/ + * @function npmPackagesExists + * + * Loops through an array and checks if a package is registered + * on npm and throws an error if it is not from @checkEachPackage + * + * @param { Array } pkg - Array of packages to check existence of + * @returns { Array } resolvePackages - Returns an process to install the pkg + */ module.exports = function npmPackagesExists(addons) { - return addons.map( pkg => checkEachPackage(pkg)); + return addons.map(pkg => checkEachPackage(pkg)); }; /* -* @function checkEachPackage -* -* Checks if a package is registered on npm and throws if it is not -* -* @param { Object } pkg - pkg to check existence of -* @returns { } resolvePackages - Returns an process to install the pkg -*/ + * @function checkEachPackage + * + * Checks if a package is registered on npm and throws if it is not + * + * @param { Object } pkg - pkg to check existence of + * @returns { } resolvePackages - Returns an process to install the pkg + */ function checkEachPackage(pkg) { - return npmExists(pkg).then( (moduleExists) => { + return npmExists(pkg).then((moduleExists) => { if(!moduleExists) { Error.stackTraceLimit = 0; - throw new TypeError('Package isn\'t registered on npm.'); + throw new TypeError("Package isn't registered on npm."); } - if (moduleExists) { + if(moduleExists) { return resolvePackages(pkg); } }).catch(err => { diff --git a/lib/utils/resolve-packages.js b/lib/utils/resolve-packages.js index 8f8f5587272..96201159fae 100644 --- a/lib/utils/resolve-packages.js +++ b/lib/utils/resolve-packages.js @@ -1,65 +1,70 @@ -const spawn = require('cross-spawn'); -const creator = require('../creator/index'); -const path = require('path'); -const chalk = require('chalk'); +"use strict"; + +const spawn = require("cross-spawn"); +const creator = require("../creator/index"); +const path = require("path"); +const chalk = require("chalk"); /* -* @function processPromise -* -* Attaches a promise to the installation of the package -* -* @param { Function } child - The function to attach a promise to -* @returns { } promise - Returns a promise to the installation -*/ + * @function processPromise + * + * Attaches a promise to the installation of the package + * + * @param { Function } child - The function to attach a promise to + * @returns { } promise - Returns a promise to the installation + */ function processPromise(child) { return new Promise(function(resolve, reject) { //eslint-disable-line - child.addListener('error', reject); - child.addListener('exit', resolve); + child.addListener("error", reject); + child.addListener("exit", resolve); }); } /* -* @function spawnChild -* -* Spawns a new process that installs the addon/dependency -* -* @param { String } pkg - The dependency to be installed -* @returns { } spawn - Installs the package -*/ + * @function spawnChild + * + * Spawns a new process that installs the addon/dependency + * + * @param { String } pkg - The dependency to be installed + * @returns { } spawn - Installs the package + */ function spawnChild(pkg) { - return spawn('npm', ['install', '--save', pkg], { stdio: 'inherit', customFds: [0, 1, 2] }); + return spawn("npm", ["install", "--save", pkg], { + stdio: "inherit", + customFds: [0, 1, 2] + }); //return spawn('npm', ['install', '--save', pkg]); } /* -* @function resolvePackages -* -* Resolves the package after it is validated, later sending it to the creator -* to be validated -* -* @param { String } pkg - The dependency to be installed -* @returns { } creator - Validates the dependency and builds -* the webpack configuration -*/ + * @function resolvePackages + * + * Resolves the package after it is validated, later sending it to the creator + * to be validated + * + * @param { String } pkg - The dependency to be installed + * @returns { } creator - Validates the dependency and builds + * the webpack configuration + */ module.exports = function resolvePackages(pkg) { Error.stackTraceLimit = 30; - return processPromise(spawnChild(pkg)).then( () => { + return processPromise(spawnChild(pkg)).then(() => { try { - let loc = path.join('..', '..', 'node_modules', pkg); + let loc = path.join("..", "..", "node_modules", pkg); creator(loc, null); } catch(err) { - console.log('Package wasn\'t validated correctly..'); - console.log('Submit an issue for', pkg, 'if this persists'); - console.log('\nReason: \n'); + console.log("Package wasn't validated correctly.."); + console.log("Submit an issue for", pkg, "if this persists"); + console.log("\nReason: \n"); console.error(chalk.bold.red(err)); process.exit(1); } }).catch(err => { - console.log('Package Coudln\'t be installed, aborting..'); - console.log('\nReason: \n'); + console.log("Package Coudln't be installed, aborting.."); + console.log("\nReason: \n"); console.error(chalk.bold.red(err)); process.exit(1); }); diff --git a/lib/utils/resolve-packages.spec.js b/lib/utils/resolve-packages.spec.js index 8ee4d39bd50..046895433fe 100644 --- a/lib/utils/resolve-packages.spec.js +++ b/lib/utils/resolve-packages.spec.js @@ -1,33 +1,33 @@ -'use strict'; +"use strict"; -const getLoc = require('../../__mocks__/inquirer/resolve.mock'); +const getLoc = require("../../__mocks__/inquirer/resolve.mock"); -describe('resolve-packages', () => { +describe("resolve-packages", () => { let moduleLoc; afterEach(() => { moduleLoc = null; }); - it('should resolve a location of a published module', () => { - moduleLoc = getLoc(['webpack-addons-ylvis']); - expect(moduleLoc).toEqual(['../../node_modules/webpack-addons-ylvis']); + it("should resolve a location of a published module", () => { + moduleLoc = getLoc(["webpack-addons-ylvis"]); + expect(moduleLoc).toEqual(["../../node_modules/webpack-addons-ylvis"]); }); - it('should be empty if argument is blank', () => { + it("should be empty if argument is blank", () => { // normally caught before getting resolved - moduleLoc = getLoc([' ']); - expect(moduleLoc).toEqual(['../../node_modules/ ']); + moduleLoc = getLoc([" "]); + expect(moduleLoc).toEqual(["../../node_modules/ "]); }); - it('should resolve multiple locations of published modules', () => { + it("should resolve multiple locations of published modules", () => { /* we're testing multiple paths here. At Github this up for discussion, because if * we validate each package on each run, we can catch and build the questions in init gradually * while we get one filepath at the time. If not, this is a workaround. */ - moduleLoc = getLoc(['webpack-addons-ylvis', 'webpack-addons-noop']); + moduleLoc = getLoc(["webpack-addons-ylvis", "webpack-addons-noop"]); expect(moduleLoc).toEqual( - ['../../node_modules/webpack-addons-ylvis', '../../node_modules/webpack-addons-noop'] + ["../../node_modules/webpack-addons-ylvis", "../../node_modules/webpack-addons-noop"] ); }); }); diff --git a/package.json b/package.json index 43f84a140f3..ddc99f77ec8 100644 --- a/package.json +++ b/package.json @@ -16,61 +16,61 @@ "node": ">=4.0.0" }, "scripts": { - "lint:bin": "eslint ./bin", - "lint:lib": "eslint ./lib", - "lint:test": "eslint ./__mocks__", + "lint": "eslint \"**/*.js\"", + "lint:codeOnly": "eslint \"{lib,bin,__mocks__}/**/!(__testfixtures__)/*.js\" \"{lib,bin,__mocks__}/**.js\"", "lint:staged": "lint-staged", - "lint": "npm run lint:bin && npm run lint:lib && npm run lint:test", - "install-commit-validator": "fit-commit-js install", + "pretest": "npm run lint", "test": "jest --coverage" }, + "lint-staged": { + "{lib,bin,__mocks__}/**/!(__testfixtures__)/**.js": [ + "eslint --fix", + "git add" + ] + }, + "pre-commit": "lint:staged", "dependencies": { "babel-code-frame": "^6.22.0", - "babel-core": "^6.21.0", - "babel-preset-es2015": "^6.18.0", - "babel-preset-stage-3": "^6.17.0", - "chalk": "^1.1.3", - "cross-spawn": "^5.0.1", + "babel-core": "^6.25.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-stage-3": "^6.24.1", + "chalk": "^2.0.1", + "cross-spawn": "^5.1.0", "diff": "^3.2.0", - "enhanced-resolve": "^3.0.2", - "fit-commit-js": "^0.3.1", - "got": "^6.6.3", - "inquirer": "^2.0.0", - "interpret": "^1.0.1", - "jscodeshift": "^0.3.30", - "listr": "^0.11.0", - "loader-utils": "^0.2.16", + "enhanced-resolve": "^3.3.0", + "got": "^7.1.0", + "inquirer": "^3.1.1", + "interpret": "^1.0.3", + "jscodeshift": "^0.3.32", + "listr": "^0.12.0", + "loader-utils": "^1.1.0", "lodash": "^4.17.4", "p-each-series": "^1.0.0", "p-lazy": "^1.0.0", "recast": "git://github.com/kalcifer/recast.git#bug/allowbreak", "rx": "^4.1.0", - "supports-color": "^3.1.2", - "webpack": "^2.2.0-rc.0", - "webpack-addons": "0.0.20", + "supports-color": "^4.1.0", + "webpack": "^3.0.0", + "webpack-addons": "1.1.2", "webpack-addons-ylvis": "0.0.34", - "yargs": "^6.5.0", - "yeoman-environment": "^1.6.6", + "yargs": "^8.0.2", + "yeoman-environment": "^2.0.0", "yeoman-generator": "git://github.com/ev1stensberg/generator.git#Feature-getArgument" }, "devDependencies": { - "ajv": "^4.11.3", - "ajv-keywords": "^1.5.1", - "babel-cli": "^6.18.0", - "babel-eslint": "^6.1.2", - "babel-jest": "^19.0.0", - "babel-polyfill": "^6.20.0", - "eslint": "^3.12.2", - "eslint-plugin-node": "^3.0.5", - "jest": "^19.0.2", - "lint-staged": "^3.2.8", - "pre-commit": "^1.2.2" - }, - "lint-staged": { - "*.js": [ - "eslint --fix", - "git add" - ] - }, - "pre-commit": "lint:staged" + "ajv": "^5.2.0", + "ajv-keywords": "^2.1.0", + "babel-cli": "^6.24.1", + "babel-eslint": "^7.2.3", + "babel-jest": "^20.0.3", + "babel-polyfill": "^6.23.0", + "eslint": "^4.1.1", + "eslint-plugin-node": "^5.1.0", + "eslint-plugin-prettier": "^2.1.2", + "jest": "^20.0.4", + "jest-cli": "^20.0.4", + "lint-staged": "^4.0.0", + "pre-commit": "^1.2.2", + "prettier": "^1.5.2" + } }