vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.76k stars 6.33k forks source link

Worker file missing in bundle in subsequent build until vue.config.js get modified #6056

Open jackysee opened 3 years ago

jackysee commented 3 years ago

Version

4.5.8

Reproduction link

https://github.com/jackysee/workertest

Environment info

Environment Info:

  System:
    OS: macOS 10.15.7
    CPU: (4) x64 Intel(R) Core(TM) i7-5650U CPU @ 2.20GHz
  Binaries:
    Node: 14.15.0 - /var/folders/0m/_myg74lx1zv_nnvqxfpy1cp40000gn/T/fnm-shell-3114332/bin/node
    Yarn: Not Found
    npm: 6.14.8 - /var/folders/0m/_myg74lx1zv_nnvqxfpy1cp40000gn/T/fnm-shell-3114332/bin/npm
  Browsers:
    Chrome: 86.0.4240.198
    Edge: Not Found
    Firefox: 76.0.1
    Safari: 14.0
  npmPackages:
    @vue/babel-helper-vue-jsx-merge-props:  1.2.1
    @vue/babel-helper-vue-transform-on:  1.0.0-rc.2
    @vue/babel-plugin-jsx:  1.0.0-rc.3
    @vue/babel-plugin-transform-vue-jsx:  1.2.1
    @vue/babel-preset-app:  4.5.8
    @vue/babel-preset-jsx:  1.2.4
    @vue/babel-sugar-composition-api-inject-h:  1.2.1
    @vue/babel-sugar-composition-api-render-instance:  1.2.4
    @vue/babel-sugar-functional-vue:  1.2.2
    @vue/babel-sugar-inject-h:  1.2.2
    @vue/babel-sugar-v-model:  1.2.3
    @vue/babel-sugar-v-on:  1.2.3
    @vue/cli-overlay:  4.5.8
    @vue/cli-plugin-babel: ~4.5.0 => 4.5.8
    @vue/cli-plugin-eslint: ~4.5.0 => 4.5.8
    @vue/cli-plugin-router:  4.5.8
    @vue/cli-plugin-vuex:  4.5.8
    @vue/cli-service: ~4.5.0 => 4.5.8
    @vue/cli-shared-utils:  4.5.8
    @vue/component-compiler-utils:  3.2.0
    @vue/preload-webpack-plugin:  1.1.2
    @vue/web-component-wrapper:  1.2.0
    eslint-plugin-vue: ^6.2.2 => 6.2.2
    vue: ^2.6.11 => 2.6.12
    vue-eslint-parser:  7.1.1
    vue-hot-reload-api:  2.3.4
    vue-loader:  15.9.5 (16.0.0-rc.1)
    vue-style-loader:  4.1.2
    vue-template-compiler: ^2.6.11 => 2.6.12
    vue-template-es2015-compiler:  1.9.1
  npmGlobalPackages:
    @vue/cli: 4.5.8

Steps to reproduce

  1. npm run build, should see the bundle has a worker file, which is created by the worker-loader
  2. npm run build again, the worker file is missing.
  3. modify vue.config.js, add a comment
  4. npm run build, the worker file appear in the bundle again.

What is expected?

The build should be consistent. The worker file should appear in the final bundle in every build.

What is actually happening?

First build

~/Documents/Programs/workertest master*
❯ npm run build

> workertest@0.1.0 build /Users/jacky/Documents/Programs/workertest
> vue-cli-service build

⠇  Building for production...

 DONE  Compiled successfully in 9310ms                                                                      12:02:41 AM

  File                                      Size                                Gzipped

  dist/js/chunk-vendors.5e5f0ab3.js         89.95 KiB                           32.23 KiB
  dist/js/app.8d248e5d.js                   3.70 KiB                            1.46 KiB
  dist/js/file.worker.bfbaf1e6.worker.js    1.04 KiB                            0.52 KiB
  dist/css/app.d40fc157.css                 0.16 KiB                            0.14 KiB

  Images and other types of assets omitted.

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html

2nd build

❯ npm run build

> workertest@0.1.0 build /Users/jacky/Documents/Programs/workertest
> vue-cli-service build

⠙  Building for production...

 DONE  Compiled successfully in 1857ms                                                                      12:02:47 AM

  File                                 Size                                   Gzipped

  dist/js/chunk-vendors.5e5f0ab3.js    89.95 KiB                              32.23 KiB
  dist/js/app.8d248e5d.js              3.70 KiB                               1.46 KiB
  dist/css/app.d40fc157.css            0.16 KiB                               0.14 KiB

  Images and other types of assets omitted.

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html

Looks like some caching issue here?

vue.config.js

module.exports = {
  chainWebpack: config => {
    //change this file
    config.module
      .rule("worker")
      .test(/worker\.js$/)
      .use("worker-loader")
      .loader("worker-loader")
      .end();
  }
};

HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
import Worker from "./file.worker";
export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  created() {
    const w = new Worker();
    w.postMessage({ a: 1 });
    w.onmessage = function(e) {
      console.log("onmessage", e);
    };
  }
};
</script>

file.worker.js

onmessage = function(event) {
  var workerResult = event.data;
  workerResult.onmessage = true;
  postMessage(workerResult);
};
fangbinwei commented 3 years ago

At present, some problems are caused by cache-loader. I think everything will be better after supporting webpack5, since cache-loader is deprecated.

For file.worker.js, the loader used is[cache-loader, babel-loader, worker-loader] In short. First build, worker-loader.pitch will generate file.worker.xx.js chunk asynchronously. Second build, cache-loader.pitch return directly because of cache hit, and worker-loader.pitch is skipped.

So workaround is changing loader order to [worker-loader, cache-loader, babel-loader], so that worker-loader.pitch won't be skipped.

/** @type {import('@vue/cli-service').ProjectOptions} */
module.exports = {
  chainWebpack: config => {
    //change this file
    config.module
      .rule("worker")
+      .before('js')
      .test(/worker\.js$/)
      .use("worker-loader")
      .loader("worker-loader")
      .end();
  }
};