uglifyJsPlugin.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. const {
  2. findPluginsByName,
  3. safeTraverse,
  4. createProperty,
  5. getRequire,
  6. findPluginsArrayAndRemoveIfEmpty
  7. } = require("../../utils/ast-utils");
  8. /**
  9. *
  10. * Transform which:
  11. * - Removes UglifyWebpackPlugin from plugins array, if no options is passed to the plugin.
  12. * and adds `optimization.minimize: true` to config
  13. *
  14. * - If any configuration is passed to UglifyWebpackPlugin
  15. * plugin instantiation is moved to `optimization.minimizer`.
  16. *
  17. * @param {Object} j - jscodeshift top-level import
  18. * @param {Node} ast - jscodeshift ast to transform
  19. * @returns {Node} ast - jscodeshift ast
  20. */
  21. module.exports = function(j, ast) {
  22. let pluginVariableAssignment;
  23. const searchForRequirePlugin = ast
  24. .find(j.VariableDeclarator)
  25. .filter(
  26. j.filters.VariableDeclarator.requiresModule("uglifyjs-webpack-plugin")
  27. );
  28. /**
  29. * Look for a variable declaration which requires uglifyjs-webpack-plugin
  30. * saves the name of this variable.
  31. */
  32. searchForRequirePlugin.forEach(node => {
  33. pluginVariableAssignment = node.value.id.name;
  34. });
  35. pluginVariableAssignment = !pluginVariableAssignment
  36. ? "webpack.optimize.UglifyJsPlugin"
  37. : pluginVariableAssignment;
  38. findPluginsByName(j, ast, [pluginVariableAssignment]).forEach(node => {
  39. let expressionContent;
  40. const configBody = safeTraverse(node, ["parent", "parent", "parent"]);
  41. // options passed to plugin
  42. const pluginOptions = node.value.arguments;
  43. /**
  44. * check if there are any options passed to UglifyWebpackPlugin
  45. * If so, they are moved to optimization.minimizer.
  46. * Otherwise, rely on default options
  47. */
  48. if (pluginOptions.length) {
  49. /*
  50. * If user is using UglifyJsPlugin directly from webpack
  51. * transformation must:
  52. * - remove it
  53. * - add require for uglify-webpack-plugin
  54. * - add to minimizer
  55. */
  56. if (pluginVariableAssignment.includes("webpack")) {
  57. // create require for uglify-webpack-plugin
  58. const pathRequire = getRequire(
  59. j,
  60. "UglifyJsPlugin",
  61. "uglifyjs-webpack-plugin"
  62. );
  63. // append to source code.
  64. ast
  65. .find(j.Program)
  66. .replaceWith(p =>
  67. j.program([].concat(pathRequire).concat(p.value.body))
  68. );
  69. expressionContent = j.property(
  70. "init",
  71. j.identifier("minimizer"),
  72. j.arrayExpression([
  73. j.newExpression(j.identifier("UglifyJsPlugin"), [pluginOptions[0]])
  74. ])
  75. );
  76. } else {
  77. expressionContent = j.property(
  78. "init",
  79. j.identifier("minimizer"),
  80. j.arrayExpression([node.value])
  81. );
  82. }
  83. } else {
  84. searchForRequirePlugin.forEach(node => j(node).remove());
  85. }
  86. const minimizeProperty = createProperty(j, "minimize", "true");
  87. // creates optimization property at the body of the config.
  88. if (expressionContent) {
  89. configBody.value.properties.push(
  90. j.property(
  91. "init",
  92. j.identifier("optimization"),
  93. j.objectExpression([minimizeProperty, expressionContent])
  94. )
  95. );
  96. } else {
  97. configBody.value.properties.push(
  98. j.property(
  99. "init",
  100. j.identifier("optimization"),
  101. j.objectExpression([minimizeProperty])
  102. )
  103. );
  104. }
  105. // remove the old Uglify plugin from Plugins array.
  106. j(node).remove();
  107. });
  108. findPluginsArrayAndRemoveIfEmpty(j, ast);
  109. return ast;
  110. };