Webpack, удаление комментариев из удаленного приложения Angular CLI не работает

У меня есть удаленное приложение Angular CLI, которое выдает комментарии «независимо от того, что» я делаю с настройками UglifyJs.

Я последовал совету из здесь, здесь и в разных местах, но ничего из этого не работает.

Я не уверен, где в порядке плагинов я должен разместить UglifyJsPlugin. Я пробовал на первой позиции, последней позиции, второй позиции и одновременно на всех остальных позициях.

Может быть какие-то настройки в других плагинах мешают?

Я запускаю это в Windows с "build:prod": "set NODE_ENV=production&&webpack --define process.env.NODE_ENV=\"'production'\""

/* eslint-disable node/no-unpublished-require */
/* eslint-disable node/no-extraneous-require */
const path = require('path');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer');
const postcssUrl = require('postcss-url');
const cssnano = require('cssnano');

const { NoEmitOnErrorsPlugin } = require('webpack');
const { GlobCopyWebpackPlugin, BaseHrefWebpackPlugin } = require(
  '@angular/cli/plugins/webpack');
const { CommonsChunkPlugin, UglifyJsPlugin } = require('webpack').optimize;
const { AotPlugin } = require('@ngtools/webpack');

const nodeModules = path.join(process.cwd(), 'node_modules');
const genDirNodeModules = path.join(
  process.cwd(),
  './src',
  '$$_gendir',
  'node_modules');
const entryPoints = [
  'inline', 'polyfills', 'sw-register', 'scripts', 'styles', 'vendor', 'main'];
const minimizeCss = false;
const baseHref = '';
const deployUrl = '';
// safe settings based on: https://github.com/ben-eb/cssnano/issues/358#issuecomment-283696193:
const postcssPlugins = function() {
  // const importantCommentRe =
  //   /@preserve|@license|[@#]\s*source(?:Mapping)?URL|^!/i;
  const minimizeOptions = {
    autoprefixer: false,
    safe: true,
    mergeLonghand: false,
    discardComments: {
      remove: (comment) => true,
      // !importantCommentRe.test(comment)
    },
  };
  return [
    postcssUrl({
      url: (URL) => {
        // Only convert root relative URLs, which CSS-Loader won't process
        // into require().
        if (!URL.startsWith('/') || URL.startsWith('//')) {
          return URL;
        }
        if (deployUrl.match(/:\/\//)) {
          // If deployUrl contains a scheme, ignore baseHref use deployUrl
          // as is.
          return `${deployUrl.replace(/\/$/, '')}${URL}`;
        } else if (baseHref.match(/:\/\//)) {
          // If baseHref contains a scheme, include it as is.
          return baseHref.replace(/\/$/, '') +
            `/${deployUrl}/${URL}`.replace(/\/\/+/g, '/');
        } else {
          // Join together base-href, deploy-url and the original URL.
          // Also dedupe multiple slashes into single ones.
          return `/${baseHref}/${deployUrl}/${URL}`.replace(/\/\/+/g, '/');
        }
      },
    }),
    autoprefixer(),
  ].concat(minimizeCss ? [cssnano(minimizeOptions)] : []);
};

const isProduction = process.env.NODE_ENV === 'production';

module.exports = {
  'devtool': 'none', // 'source-map',
  'resolve': {
    'extensions': [
      '.ts',
      '.js',
    ],
    'modules': [
      './node_modules',
      './node_modules',
    ],
  },
  'resolveLoader': {
    'modules': [
      './node_modules',
    ],
  },
  'entry': {
    'main': [
      './src\\main.ts',
    ],
    'polyfills': [
      './src\\polyfills.ts',
    ],
    'scripts': [
      'script-loader!./node_modules\\moment\\min\\moment.min.js',
      'script-loader!./node_modules\\pptxgenjs\\dist\\pptxgen.js',
      'script-loader!./node_modules\\pptxgenjs\\dist\\pptxgen.shapes.js',
      'script-loader!./node_modules\\pptxgenjs\\libs\\jszip.min.js',
      'script-loader!./node_modules\\pptxgenjs\\libs\\jquery.min.js',
    ],
    'styles': [
      './src\\styles.scss',
    ],
  },
  'output': {
    'path': path.join(process.cwd(), 'dist'),
    'filename': '[name].bundle.js',
    'chunkFilename': '[id].chunk.js',
  },
  'module': {
    'rules': [
      // {
      //   'enforce': 'pre',
      //   'test': /\.js$/,
      //   'loader': 'source-map-loader',
      //   'exclude': [
      //     /\/node_modules\//,
      //   ],
      // },
      {
        'test': /\.json$/,
        'loader': 'json-loader',
      },
      {
        'test': /\.html$/,
        'loader': 'raw-loader',
      },
      {
        'test': /\.(eot|svg)$/,
        'loader': 'file-loader?name=[name].[hash:20].[ext]',
      },
      {
        'test': /\.(jpg|png|gif|otf|ttf|woff|woff2|cur|ani)$/,
        'loader': 'url-loader?name=[name].[hash:20].[ext]&limit=10000',
      },
      {
        'exclude': [
          path.join(process.cwd(), 'src\\styles.scss'),
        ],
        'test': /\.css$/,
        'use': [
          'exports-loader?module.exports.toString()',
          {
            'loader': 'css-loader',
            'options': {
              'sourceMap': false,
              'importLoaders': 1,
            },
          },
          {
            'loader': 'postcss-loader',
            'options': {
              'ident': 'postcss',
              'plugins': postcssPlugins,
            },
          },
        ],
      },
      {
        'exclude': [
          path.join(process.cwd(), 'src\\styles.scss'),
        ],
        'test': /\.scss$|\.sass$/,
        'use': [
          'exports-loader?module.exports.toString()',
          {
            'loader': 'css-loader',
            'options': {
              'sourceMap': false,
              'importLoaders': 1,
            },
          },
          {
            'loader': 'postcss-loader',
            'options': {
              'ident': 'postcss',
              'plugins': postcssPlugins,
            },
          },
          {
            'loader': 'sass-loader',
            'options': {
              'sourceMap': false,
              'precision': 8,
              'includePaths': [],
            },
          },
        ],
      },
      {
        'exclude': [
          path.join(process.cwd(), 'src\\styles.scss'),
        ],
        'test': /\.less$/,
        'use': [
          'exports-loader?module.exports.toString()',
          {
            'loader': 'css-loader',
            'options': {
              'sourceMap': false,
              'importLoaders': 1,
            },
          },
          {
            'loader': 'postcss-loader',
            'options': {
              'ident': 'postcss',
              'plugins': postcssPlugins,
            },
          },
          {
            'loader': 'less-loader',
            'options': {
              'sourceMap': false,
            },
          },
        ],
      },
      {
        'exclude': [
          path.join(process.cwd(), 'src\\styles.scss'),
        ],
        'test': /\.styl$/,
        'use': [
          'exports-loader?module.exports.toString()',
          {
            'loader': 'css-loader',
            'options': {
              'sourceMap': false,
              'importLoaders': 1,
            },
          },
          {
            'loader': 'postcss-loader',
            'options': {
              'ident': 'postcss',
              'plugins': postcssPlugins,
            },
          },
          {
            'loader': 'stylus-loader',
            'options': {
              'sourceMap': false,
              'paths': [],
            },
          },
        ],
      },
      {
        'include': [
          path.join(process.cwd(), 'src\\styles.scss'),
        ],
        'test': /\.css$/,
        'use': [
          'style-loader',
          {
            'loader': 'css-loader',
            'options': {
              'sourceMap': false,
              'importLoaders': 1,
            },
          },
          {
            'loader': 'postcss-loader',
            'options': {
              'ident': 'postcss',
              'plugins': postcssPlugins,
            },
          },
        ],
      },
      {
        'include': [
          path.join(process.cwd(), 'src\\styles.scss'),
        ],
        'test': /\.scss$|\.sass$/,
        'use': [
          'style-loader',
          {
            'loader': 'css-loader',
            'options': {
              'sourceMap': false,
              'importLoaders': 1,
            },
          },
          {
            'loader': 'postcss-loader',
            'options': {
              'ident': 'postcss',
              'plugins': postcssPlugins,
            },
          },
          {
            'loader': 'sass-loader',
            'options': {
              'sourceMap': false,
              'precision': 8,
              'includePaths': [],
            },
          },
        ],
      },
      {
        'include': [
          path.join(process.cwd(), 'src\\styles.scss'),
        ],
        'test': /\.less$/,
        'use': [
          'style-loader',
          {
            'loader': 'css-loader',
            'options': {
              'sourceMap': false,
              'importLoaders': 1,
            },
          },
          {
            'loader': 'postcss-loader',
            'options': {
              'ident': 'postcss',
              'plugins': postcssPlugins,
            },
          },
          {
            'loader': 'less-loader',
            'options': {
              'sourceMap': false,
            },
          },
        ],
      },
      {
        'include': [
          path.join(process.cwd(), 'src\\styles.scss'),
        ],
        'test': /\.styl$/,
        'use': [
          'style-loader',
          {
            'loader': 'css-loader',
            'options': {
              'sourceMap': false,
              'importLoaders': 1,
            },
          },
          {
            'loader': 'postcss-loader',
            'options': {
              'ident': 'postcss',
              'plugins': postcssPlugins,
            },
          },
          {
            'loader': 'stylus-loader',
            'options': {
              'sourceMap': false,
              'paths': [],
            },
          },
        ],
      },
      {
        'test': /\.ts$/,
        'loader': '@ngtools/webpack',
      },
    ],
  },
  'plugins': [
    new NoEmitOnErrorsPlugin(),
    new UglifyJsPlugin({
      comments: false,
      sourceMap: false,
      compress: {
        sequences: true,
        dead_code: true,
        conditionals: true,
        booleans: true,
        unused: true,
        if_return: true,
        join_vars: true,
        drop_console: true,
      },
      // mangle: {
      //   except: ['$super', '$', 'exports', 'require'],
      // },
      output: {
        comments: false,
      },
    }),
    new GlobCopyWebpackPlugin({
      'patterns': [
        'assets',
        'favicon.ico',
      ],
      'globOptions': {
        'cwd': 'c:\\dev\\engage\\js-engage\\src',
        'dot': true,
        'ignore': '**/.gitkeep',
      },
    }),
    new ProgressPlugin(),
    new HtmlWebpackPlugin({
      'template': './src\\index.html',
      'filename': './index.html',
      'hash': false,
      'inject': true,
      'compile': true,
      'favicon': false,
      'minify': false,
      'cache': true,
      'showErrors': true,
      'chunks': 'all',
      'excludeChunks': [],
      'title': 'Webpack App',
      'xhtml': true,
      'chunksSortMode': function sort(left, right) {
        let leftIndex = entryPoints.indexOf(left.names[0]);
        let rightindex = entryPoints.indexOf(right.names[0]);
        if (leftIndex > rightindex) {
          return 1;
        } else if (leftIndex < rightindex) {
          return -1;
        } else {
          return 0;
        }
      },
    }),
    new BaseHrefWebpackPlugin({}),
    new CommonsChunkPlugin({
      'name': 'inline',
      'minChunks': null,
    }),
    new CommonsChunkPlugin({
      'name': 'vendor',
      'minChunks': (module) => module.resource &&
      (module.resource.startsWith(nodeModules) || module.resource.startsWith(
        genDirNodeModules)),
      'chunks': [
        'main',
      ],
    }),
    new AotPlugin({
      'mainPath': 'main.ts',
      'hostReplacementPaths': {
        'environments\\environment.ts': isProduction
          ? 'environments\\environment.prod.ts'
          : 'environments\\environment.ts',
      },
      'exclude': [],
      'tsConfigPath': 'src\\tsconfig.app.json',
      'skipCodeGeneration': true,
    }),
  ],
  'node': {
    'fs': 'empty',
    'global': true,
    'crypto': 'empty',
    'tls': 'empty',
    'net': 'empty',
    'process': true,
    'module': false,
    'clearImmediate': false,
    'setImmediate': false,
  },
  'devServer': {
    'historyApiFallback': true,
  },
};

Обновление:

Вместо 'none', что неверно, я поставил devtools: false, но это не помогло.

Кроме того, я попробовал remove-comments-loader и webpack-comment-remover-loader, но это не помогло.

На самом деле я только что понял, что комментарии появляются в main.bundle.js.map — и даже если я отключил исходные карты, этот файл сохранился. Когда я вручную удалил ранее существовавшие карты и сделал новую сборку с удаленными исходными картами, они не были переделаны, и комментарии не были включены в файлы javascript.

Tl;dr: ошибка пользователя. Отключите исходные карты, удалите все ранее существовавшие исходные карты, перестройте.


person Mikal Madsen    schedule 03.07.2017    source источник
comment
Вы выбросили существующий проект angular-cli?   -  person Darshita    schedule 03.07.2017
comment
Да. Это то, что создало конфигурацию веб-пакета (в которую я добавил некоторые изменения)   -  person Mikal Madsen    schedule 03.07.2017
comment
Я сделал то же самое, и мой проект работает отлично. Вы получаете сообщение об ошибке в uglifyjs? Должен ли я поделиться webpack.config.js?   -  person Darshita    schedule 03.07.2017
comment
Я получаю предупреждения, но ошибок нет, компилируется нормально. Да, здорово, если вы поделитесь своей конфигурацией. Не уверен, что безопасно удалить.   -  person Mikal Madsen    schedule 03.07.2017


Ответы (1)


Вот webpack.config.js файл. Внесите соответствующие изменения.

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');

const { NoEmitOnErrorsPlugin, LoaderOptionsPlugin } = require('webpack');
const { BaseHrefWebpackPlugin, GlobCopyWebpackPlugin } = require('@angular/cli/plugins/webpack');
const { CommonsChunkPlugin } = require('webpack').optimize;
const { AotPlugin } = require('@ngtools/webpack');

const nodeModules = path.join(process.cwd(), 'node_modules');
const entryPoints = ["inline","polyfills","sw-register","styles","vendor","main"];




module.exports = {
  "devtool": "source-map",
  "resolve": {
    "extensions": [
      ".ts",
      ".js"
    ],
    "modules": [
      "./node_modules"
    ]
  },
  "resolveLoader": {
    "modules": [
      "./node_modules"
    ]
  },
  "entry": {
    "main": [
      "./src\\main.ts"
    ],
    "polyfills": [
      "./src\\polyfills.ts"
    ],
    "styles": [
      "./src\\styles.css"
    ]
  },
  "output": {
    "path": path.join(process.cwd(), "dist"),
    "filename": "[name].bundle.js",
    "chunkFilename": "[id].chunk.js"
  },
  "module": {
    "rules": [
      {
        "enforce": "pre",
        "test": /\.js$/,
        "loader": "source-map-loader",
        "exclude": [
          /\/node_modules\//
        ]
      },
      {
        "test": /\.json$/,
        "loader": "json-loader"
      },
      {
        "test": /\.html$/,
        "loader": "raw-loader"
      },
      {
        "test": /\.(eot|svg)$/,
        "loader": "file-loader?name=[name].[ext]"
      },
      {
        "test": /\.(jpg|png|gif|otf|ttf|woff|woff2|cur|ani)$/,
        "loader": "url-loader?name=[name].[ext]&limit=10000"
      },
      {
        "exclude": [
          path.join(process.cwd(), "src\\styles.css")
        ],
        "test": /\.css$/,
        "loaders": [
          "exports-loader?module.exports.toString()",
          "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
          "postcss-loader"
        ]
      },
      {
        "exclude": [
          path.join(process.cwd(), "src\\styles.css")
        ],
        "test": /\.scss$|\.sass$/,
        "loaders": [
          "exports-loader?module.exports.toString()",
          "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
          "postcss-loader",
          "sass-loader"
        ]
      },
      {
        "exclude": [
          path.join(process.cwd(), "src\\styles.css")
        ],
        "test": /\.less$/,
        "loaders": [
          "exports-loader?module.exports.toString()",
          "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
          "postcss-loader",
          "less-loader"
        ]
      },
      {
        "exclude": [
          path.join(process.cwd(), "src\\styles.css")
        ],
        "test": /\.styl$/,
        "loaders": [
          "exports-loader?module.exports.toString()",
          "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
          "postcss-loader",
          "stylus-loader?{\"sourceMap\":false,\"paths\":[]}"
        ]
      },
      {
        "include": [
          path.join(process.cwd(), "src\\styles.css")
        ],
        "test": /\.css$/,
        "loaders": ExtractTextPlugin.extract({
  "use": [
    "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
    "postcss-loader"
  ],
  "fallback": "style-loader",
  "publicPath": ""
})
      },
      {
        "include": [
          path.join(process.cwd(), "src\\styles.css")
        ],
        "test": /\.scss$|\.sass$/,
        "loaders": ExtractTextPlugin.extract({
  "use": [
    "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
    "postcss-loader",
    "sass-loader"
  ],
  "fallback": "style-loader",
  "publicPath": ""
})
      },
      {
        "include": [
          path.join(process.cwd(), "src\\styles.css")
        ],
        "test": /\.less$/,
        "loaders": ExtractTextPlugin.extract({
  "use": [
    "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
    "postcss-loader",
    "less-loader"
  ],
  "fallback": "style-loader",
  "publicPath": ""
})
      },
      {
        "include": [
          path.join(process.cwd(), "src\\styles.css")
        ],
        "test": /\.styl$/,
        "loaders": ExtractTextPlugin.extract({
  "use": [
    "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
    "postcss-loader",
    "stylus-loader?{\"sourceMap\":false,\"paths\":[]}"
  ],
  "fallback": "style-loader",
  "publicPath": ""
})
      },
      {
        "test": /\.ts$/,
        "loader": "@ngtools/webpack",
        "exclude": [
          /\.(spec|e2e)\.ts$/
        ]
      }
    ]
  },
  "plugins": [
    new NoEmitOnErrorsPlugin(),
    new HtmlWebpackPlugin({
      "template": "./src\\index.html",
      "filename": "./index.html",
      "hash": false,
      "inject": true,
      "compile": true,
      "favicon": false,
      "minify": false,
      "cache": true,
      "showErrors": true,
      "chunks": "all",
      "excludeChunks": [],
      "title": "Webpack App",
      "xhtml": true,
      "chunksSortMode": function sort(left, right) {
        let leftIndex = entryPoints.indexOf(left.names[0]);
        let rightindex = entryPoints.indexOf(right.names[0]);
        if (leftIndex > rightindex) {
            return 1;
        }
        else if (leftIndex < rightindex) {
            return -1;
        }
        else {
            return 0;
        }
    }
    }),
    new BaseHrefWebpackPlugin({}),
    new CommonsChunkPlugin({
      "name": "inline",
      "minChunks": null
    }),
    new CommonsChunkPlugin({
      "name": "vendor",
      "minChunks": (module) => module.resource && module.resource.startsWith(nodeModules),
      "chunks": [
        "main"
      ]
    }),
    new GlobCopyWebpackPlugin({
      "patterns": [
        "assets",
        "favicon.ico"
      ],
      "globOptions": {
        "cwd": "D:\\Webpack\\demo\\src",
        "dot": true,
        "ignore": "**/.gitkeep"
      }
    }),
    new ProgressPlugin(),
    new ExtractTextPlugin({
      "filename": "[name].bundle.css",
      "disable": true
    }),
    new LoaderOptionsPlugin({
      "sourceMap": false,
      "options": {
        "postcss": [
          autoprefixer()
        ],
        "sassLoader": {
          "sourceMap": false,
          "includePaths": []
        },
        "lessLoader": {
          "sourceMap": false
        },
        "context": ""
      }
    }),
    new AotPlugin({
      "tsConfigPath": "src\\tsconfig.json",
      "mainPath": "main.ts",
      "hostReplacementPaths": {
        "environments\\environment.ts": "environments\\environment.ts"
      },
      "exclude": [
        "**/*.spec.ts",
        "D:\\Webpack\\demo\\src\\test.ts"
      ],
      "skipCodeGeneration": true
    })
  ],
  "node": {
    "fs": "empty",
    "global": true,
    "crypto": "empty",
    "tls": "empty",
    "net": "empty",
    "process": true,
    "module": false,
    "clearImmediate": false,
    "setImmediate": false
  }
};

Надеюсь, это поможет!

person Darshita    schedule 04.07.2017
comment
Спасибо. После адаптации не помогло. - person Mikal Madsen; 04.07.2017
comment
Не ошибка, я думал, что комментарии включаются, но оказалось, что они просто включались в исходные карты, и когда я отключил исходные карты, старые исходные карты все еще хранились в папке dist. Когда я их удалил, все работает как положено. - person Mikal Madsen; 04.07.2017