Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GlobCopyWebpackPlugin loops webpack --watch for forever recompilation #5252

Closed
dmytro-y-dev opened this issue Mar 6, 2017 · 4 comments
Closed

Comments

@dmytro-y-dev
Copy link

Please provide us with the following information:

OS?

Windows 7, 8 or 10. Linux (which distribution). Mac OSX (Yosemite? El Capitan?)

Mac OS X Yosemite

Versions.

Please run ng --version. If there's nothing outputted, please run in a Terminal: node --version and paste the result here:

@angular/cli: 1.0.0-rc.0 (e)
node: 7.4.0
os: darwin x64
@angular/common: 2.4.8
@angular/compiler: 2.4.8
@angular/core: 2.4.8
@angular/forms: 2.4.8
@angular/http: 2.4.8
@angular/platform-browser: 2.4.8
@angular/platform-browser-dynamic: 2.4.8
@angular/router: 3.4.8
@angular/cli: 1.0.0-rc.0

Repro steps.

Was this an app that wasn't created using the CLI? What change did you do on your code? etc.

  1. Create some base project that depends on socket.io.
  2. ng eject webpack configuration.
  3. Specify some devtool like "devtool": "inline-source-map" (reproducable with any devtool)
  4. Add some directories inside "patterns": section. I had next:
"patterns": [
        "img",
        "favicon.ico"
      ],
  1. Run webpack --watch. It will compile bundles successfully, but will try to find socket.io.js.map on every watch iteration, and notify browser that bundles are recompiled. Again and again.

My webpack.config.js

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

const { NoEmitOnErrorsPlugin, LoaderOptionsPlugin } = require('webpack');
const { GlobCopyWebpackPlugin, BaseHrefWebpackPlugin } = 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"];
const baseHref = undefined;
const deployUrl = undefined;

module.exports = {
  "devtool": "inline-source-map",
  "resolve": {
    "extensions": [
      ".ts",
      ".js",
      ".json"
    ],
    "modules": [
      "./node_modules"
    ],
    "alias": {
        "config": "config/config.prod.js"
    }
  },
  "resolveLoader": {
    "modules": [
      "./node_modules"
    ]
  },
  "entry": {
    "main": [
      "./app/main.ts"
    ],
    "polyfills": [
      "./app/polyfills.ts"
    ],
    "styles": [
      "./dist/style.prod.css"
    ]
  },
  "output": {
    "path": path.join(process.cwd(), "dist/prod"),
    "filename": "[name].bundle.js",
    "chunkFilename": "[id].chunk.js"
  },
  "module": {
    "rules": [
      {
        "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(), "dist/style.prod.css")
        ],
        "test": /\.css$/,
        "loaders": [
          "exports-loader?module.exports.toString()",
          "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
          "postcss-loader"
        ]
      },
      {
        "exclude": [
          path.join(process.cwd(), "dist/style.prod.css")
        ],
        "test": /\.less$/,
        "loaders": [
          "exports-loader?module.exports.toString()",
          "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
          "postcss-loader",
          "less-loader"
        ]
      },
      {
        "include": [
          path.join(process.cwd(), "dist/style.prod.css")
        ],
        "test": /\.css$/,
        "loaders": ExtractTextPlugin.extract({
          "use": [
            "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
            "postcss-loader"
          ],
          "fallback": "style-loader",
          "publicPath": ""
        })
      },
      {
        "include": [
          path.join(process.cwd(), "dist/style.prod.css")
        ],
        "test": /\.less$/,
        "loaders": ExtractTextPlugin.extract({
          "use": [
            "css-loader?{\"sourceMap\":false,\"importLoaders\":1}",
            "postcss-loader",
            "less-loader"
          ],
          "fallback": "style-loader",
          "publicPath": ""
        })
      },
      {
        "test": /\.ts$/,
        "loader": "@ngtools/webpack"
      }
    ]
  },
  "plugins": [
    new NoEmitOnErrorsPlugin(),
    new GlobCopyWebpackPlugin({
      "patterns": [
        "img",
        "favicon.ico"
      ],
      "globOptions": {
        "cwd": ".",
        "dot": true,
        "ignore": "**/.gitkeep"
      }
    }),
    new ProgressPlugin(),
    new ProvidePlugin({
        $:"jquery",
        jQuery:"jquery"
    }),
    new HtmlWebpackPlugin({
      "template": "./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 ExtractTextPlugin({
      "filename": "[name].bundle.css",
      "disable": true
    }),
    new LoaderOptionsPlugin({
      "sourceMap": false,
      "options": {
        "postcss": [
          autoprefixer(),
          postcssUrl({"url": (URL) => {
            // Only convert absolute URLs, which CSS-Loader won't process into require().
            if (!URL.startsWith('/')) {
                return URL;
            }
            // Join together base-href, deploy-url and the original URL.
            // Also dedupe multiple slashes into single ones.
            return `/${baseHref || ''}/${deployUrl || ''}/${URL}`.replace(/\/\/+/g, '/');
        }})
        ],
        "lessLoader": {
          "sourceMap": false
        },
        "context": ""
      }
    }),
    new AotPlugin({
      "mainPath": "app/main.ts",
      "hostReplacementPaths": {},
      "exclude": [],
      "tsConfigPath": "tsconfig.json",
      "skipCodeGeneration": true
    })
  ],
  "node": {
    "fs": "empty",
    "global": true,
    "crypto": "empty",
    "tls": "empty",
    "net": "empty",
    "process": true,
    "module": false,
    "clearImmediate": false,
    "setImmediate": false
  }
};

The log given by the failure.

Normally this include a stack trace and some more information.

Webpack tries to resolve socket.io-client/bin/socket.io.js.map file forever.

Mention any other details that might be useful.


Thanks! We'll be in touch soon.

@dmytro-y-dev
Copy link
Author

http://imgur.com/RS2bXy1

@dmytro-y-dev
Copy link
Author

Ok, I opened issue on socket.io issue tracker (socketio/socket.io-client#1088) as well. I am not sure where the bug lies exactly :(

Minimal app to reproduce bug: https://github.com/metamaker/webpack-watches-bug

@dmytro-y-dev
Copy link
Author

Solved the problem. After debugging Webpack I figured out that it watches for changes in files that GlobCopyWebpackPlugin copies. So when GlobCopyWebpackPlugin copies, Webpack notifies watch about change, and GlobCopyWebpackPlugin copies again, and so on. This is there this cyclic behavior comes from.

Bugfix is here: https://github.com/metamaker/webpack-watches-bug/compare/bugfix/solved-bug (in short, you need to set correct watchOptions.ignored for webpack).

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant