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

Crashed when using Webpack import() #2463

Closed
fxxjdedd opened this issue Sep 7, 2018 · 28 comments
Closed

Crashed when using Webpack import() #2463

fxxjdedd opened this issue Sep 7, 2018 · 28 comments

Comments

@fxxjdedd
Copy link
Contributor

fxxjdedd commented Sep 7, 2018

Version

3.0.1

Reproduction link

https://github.com/fxxjdedd/vue-cli3-import-test.git

Node and OS info

Node 10.3.0, yarn 1.9.4, Windows10

Steps to reproduce

yarn install && yarn serve

What is expected?

running

What is actually happening?

crashed with error:

 RangeError: Maximum call stack size exceeded

  - Array.join

  - loader.js:228 Function.Module._findPath
    internal/modules/cjs/loader.js:228:56

  - loader.js:591 Function.Module._resolveFilename
    internal/modules/cjs/loader.js:591:25

  - loader.js:520 Function.Module._load
    internal/modules/cjs/loader.js:520:25

  - loader.js:650 Module.require
    internal/modules/cjs/loader.js:650:17

  - helpers.js:20 require
    internal/modules/cjs/helpers.js:20:18

  - extract-chunks.js:35 getNames
    [vue-cli3-import-test]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:35:22

  - extract-chunks.js:44 getNames
    [vue-cli3-import-test]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

概述:

这个问题是在我迁移项目到cli3时遇到的,项目中使用到了import(),并且它的参数是一个变量。
我总结了一下,出现这个问题的需要两个条件:

  1. 使用了Webpack的import()动态导入功能,且参数是一个变量(这个变量即使已经限制了文件夹范围,依然会有问题)。

  2. 包含上述行为的.js文件在多页面应用中被多个page同时引用(我实验了一下,发现至少需要3个page)。另外,更加奇怪的是,从非pages文件引入就没这个问题。

注意:

需要结合我给的reproduction项目看一下:

  1. 写了一个src/common/index.js, 用来引入pages和non-pages里的import-test模块
  2. pages中一共有4个page,在其中A、B、C三个page里的app.js中,引入common/index.js
  3. 为了验证从非pages文件夹中引入是否有问题,新建了一个no-pages文件夹
@LinusBorg
Copy link
Member

Presumably some sort of cicular dependeny problem.

https://github.com/fxxjdedd/vue-cli3-import-test/blob/master/src/common/index.js#L2-L3

let filename = 'import-test.js'
import(`@/pages/${filename}`)
  • this code will create async chunks for all components in /pages, not just import-test.js
  • Some of these components import /common/index.js

I can't judge if this is inevitable or a bug in @vue/preload-webpack-plugin

@LinusBorg LinusBorg added the needs team repro We acknowledged your report and will soon try to reproduce it label Sep 7, 2018
@fxxjdedd
Copy link
Contributor Author

fxxjdedd commented Sep 8, 2018

yeah, circular dependency is the point,but isn't it common in projects?

@Kocal
Copy link
Contributor

Kocal commented Sep 8, 2018

Not really, circular dependencies should be avoided to prevent this kind of problem.

Here for example, you can try to move your import() into a pages.js file, next to common.js. Then you will be able to import your common file in pages

@fxxjdedd
Copy link
Contributor Author

fxxjdedd commented Sep 9, 2018

you are right, but there is another confusing thing,in the demo project,if we only import '@/common' in pageA, and delete import in pageB and pageC, it won't crash.

@Kocal
Copy link
Contributor

Kocal commented Sep 9, 2018

Mmmmh, maybe because it's not "cyclic"? 🤔
I'm not sure about dependencies resolving behaviour, but pageA imports common that imports pageA that imports common: so we have pageA <-> common and webpack can resolve it properly.

But when pageA imports common that imports that all pages, all pages will import common that will import all pages... And that's a total mess 😅

@LinusBorg
Copy link
Member

Maybe it's indeed the preload-plugin we add that creates an infinite loop through the recursive call here:

https://github.com/vuejs/preload-webpack-plugin/blob/master/src/lib/extract-chunks.js#L43-L45

/cc @yyx990803

@dabaii
Copy link

dabaii commented Sep 13, 2018

在使用vue-cli2 迁移到vue-cli3过程中. 我也遇到相同的问题.

vue-cli2中index.html在根目录.

vue-cli3 默认配置中,index.html在public中.

迁移过程中我尝试把index.html移动到public,项目没有任何问题能够启动.

但是我不移动index.html(保持和vue-cli2项目目录),通过配置vue.config.js 的pages选项定义HtmlWebpackPlugin的template. 项目在编译过程中就会无法编译通过:

ERROR  Failed to compile with 1 errors                                                                                                                                                                                                                                                              15:20:37

  RangeError: Maximum call stack size exceeded

  - Array.join

  - loader.js:228 Function.Module._findPath
    internal/modules/cjs/loader.js:228:56

  - loader.js:591 Function.Module._resolveFilename
    internal/modules/cjs/loader.js:591:25

  - loader.js:520 Function.Module._load
    internal/modules/cjs/loader.js:520:25

  - loader.js:650 Module.require
    internal/modules/cjs/loader.js:650:17

  - helpers.js:20 require
    internal/modules/cjs/helpers.js:20:18

  - extract-chunks.js:35 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:35:22

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

  - extract-chunks.js:44 getNames
    [vue-cli3]/[@vue]/preload-webpack-plugin/src/lib/extract-chunks.js:44:21

整个项目我只有路由配置文件采用了import()语法. 我尝试删减路由配置测试是否是import()语法引起的问题. 在少于4个import()的情况下,项目是可以通过编译的. 4个及以上编译不通过.

但是如果不使用 vue.config.js中配置的pages.就完全没有这个问题.这让我很迷惑.

@fxxjdedd
Copy link
Contributor Author

fxxjdedd commented Sep 13, 2018

Vue-cli3 is so charming🥞, but it is still under beta, we have to wait😋.

@wuservices
Copy link

This is exploding on me in the same way in my Vue CLI 3 project with a multi-page build. It happens once certain dependencies are included.

@LinusBorg it seems like this would be avoidable if the plugin kept track of what was processed in getNames (groups) to avoid infinite recursion. Or, it could be rewritten without recursion.

I haven't groked what the plugin does where it's crashing yet, but when searching around, I found https://github.com/webpack/webpack/blob/master/lib/optimize/EnsureChunkConditionsPlugin.js (potentially very unrelated), but noticed it was tracking chunk groups in a Set().

This might be logically wrong, but at least I was able to get my app running in dev mode temporarily by breaking the recursion by adding a Set() of processedGroups:

const processedGroups = new Set()
function getNames (groups) {
  const Entrypoint = require('webpack/lib/Entrypoint')
  const names = []
  for (const group of groups) {
    if (group instanceof Entrypoint) {
      // entrypoint
      if (group.options.name) {
        names.push(group.options.name)
      }
    } else {
      if (!processedGroups.has(group)) {
        processedGroups.add(group)
        names.push(...getNames(group.parentsIterable))
      }
    }
  }
  return names
}

Seems like this should be addressable by somebody who knows what actually should happen here.

Without a fix, is it impossible to have a multi-page build with circular references?

@LinusBorg LinusBorg added bug scope: cli-service serve and removed needs team repro We acknowledged your report and will soon try to reproduce it labels Sep 18, 2018
@LinusBorg
Copy link
Member

Thanks for these valuable pointers, we will check this out as soon as we can.

If you want rot make the multi page build work for now, you could remove this plugin, which is "only" responsible for turning "normal" script tags into "preload" ones, so the build should work with out it if memory serves.

@guidetheorient
Copy link

guidetheorient commented Sep 19, 2018

cannot delete preload plugin in vue.config.js, i'm so confused.

  // vue.config.js
  chainWebpack: config => {
    config.plugins.delete('preload');
    config.plugins.delete('prefetch');
  },
// vue inspect 
/* config.plugin('preload-index') */
    new PreloadPlugin(
      {
        rel: 'preload',
        includeHtmlNames: [
          'mobile.html'
        ],
        include: {
          type: 'initial',
          entries: [
            'index'
          ]
        },
        fileBlacklist: [
          /\.map$/,
          /hot-update\.js$/
        ]
      }
    ),
    /* config.plugin('prefetch-index') */
    new PreloadPlugin(
      {
        rel: 'prefetch',
        includeHtmlNames: [
          'mobile.html'
        ],
        include: {
          type: 'asyncChunks',
          entries: [
            'index'
          ]
        }
      }
    ),
    /* config.plugin('preload-alarm') */
    new PreloadPlugin(
      {
        rel: 'preload',
        includeHtmlNames: [
          'handle-alarm.html'
        ],
        include: {
          type: 'initial',
          entries: [
            'alarm'
          ]
        },
        fileBlacklist: [
          /\.map$/,
          /hot-update\.js$/
        ]
      }
    ),
    /* config.plugin('prefetch-alarm') */
    new PreloadPlugin(
      {
        rel: 'prefetch',
        includeHtmlNames: [
          'handle-alarm.html'
        ],
        include: {
          type: 'asyncChunks',
          entries: [
            'alarm'
          ]
        }
      }
    ),

@LinusBorg
Copy link
Member

You are using the pages feature, where each page has its own instance of

  • html-webpack-plugin
  • preload-plugin
  • prefetch-plugin

... and each instance has its own name, as you can see in the output of inspect:

/* config.plugin('preload-index') */
..
 /* config.plugin('preload-alarm') */

You will have to remove all of these.

@wuservices
Copy link

wuservices commented Sep 22, 2018

Very helpful advice!

In case anybody is having trouble with this, here's the idea:

  chainWebpack: config => {
    // TODO: Remove this workaround once https://github.com/vuejs/vue-cli/issues/2463 is fixed
    // Remove preload plugins for multi-page build to prevent infinite recursion
    Object.keys(pagesObject).forEach(page => {
      config.plugins.delete(`preload-${page}`)
      config.plugins.delete(`prefetch-${page}`)
    })
  }

@lorainwings
Copy link

Thanks, it solve my same problem,
looking forward to a better solution

sendya added a commit to vueComponent/ant-design-vue-pro that referenced this issue Nov 14, 2018
@paolog22
Copy link

paolog22 commented Dec 15, 2018

@wuservices where did you get the pageObject parameter in the Object.keys(pagesObject).forEach(page => { config.plugins.delete(preload-${page}) config.plugins.delete(prefetch-${page}) }) ?

@LinusBorg
Copy link
Member

LinusBorg commented Dec 15, 2018

He likely saved the pages config that he used as a variable called pagesObject, which he then used to define the pages options as well as using it in the code above

@nkostadinov
Copy link

I had similar problem that managed to workaround by moving the pages inside webpack config in the entry section like this:

  configureWebpack: {
    entry: {
      app: './main.js',
      landing: './landing.js'
    },

@luxueyan
Copy link

luxueyan commented Jan 25, 2019

I think @vue/preload-webpack-plugin should update to support the cicular dependency like:
GoogleChromeLabs/preload-webpack-plugin#49

@viruscamp
Copy link

I have made a cli-service : ${projectDir}/build/vue-cli-service/remove-preload-prefetch.js

module.exports = (api, projectOptions) => {
  api.chainWebpack(webpackConfig => {
    // see https://github.com/vuejs/vue-cli/issues/2463
    if (projectOptions.pages) {
      Object.keys(projectOptions.pages).forEach(page => {
        webpackConfig.plugins.delete(`preload-${page}`)
        webpackConfig.plugins.delete(`prefetch-${page}`)
      })
    }
  })
}

Then use it in package.json

  "vuePlugins": {
    "service": [
      "build/vue-cli-service/remove-preload-prefetch.js"
    ]
  },

@barakbd-bluevine
Copy link

@viruscamp - I get this error on build
` this.modes = this.plugins.reduce((modes, { apply: { defaultModes }}) => {
^

TypeError: Cannot destructure property defaultModes of 'undefined' or 'null'.
at Service.modes.plugins.reduce (/opt/bluevine/node_modules/@vue/cli-service/lib/Service.js:37:48)
at Array.reduce ()
at new Service (/opt/bluevine/node_modules/@vue/cli-service/lib/Service.js:37:31)
at Object. (/opt/bluevine/node_modules/@vue/cli-service/bin/vue-cli-service.js:16:17)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! deposit_accounts_dashboard@0.1.0 build: vue-cli-service build
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the deposit_accounts_dashboard@0.1.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! /opt/bluevine/.npm/_logs/2019-02-01T02_29_03_707Z-debug.log`

@haoqunjiang
Copy link
Member

haoqunjiang commented Feb 15, 2019

@luxueyan last time I checked it was in sync with the upstream package, so I believe that commit did not fully fixed the circular dependency issue, we need to investigate further.

@paulohlimamaia
Copy link

@wuservices Thank you so much! Your workaround saved me!

Any expected plans to resolve this issue?
(Sorry if it was already resolved)

@AdictoChannel
Copy link

AdictoChannel commented May 17, 2019

@barakbd-bluevine I get the same error when using a custom vue-cli service plugin with node v12. But I don't think it is related to this issue here.
Try again with node v10.

@dalezak
Copy link

dalezak commented Jul 26, 2019

Any update @LinusBorg on this issue? I've started experiencing it as well, but can't find the underlying cause of the circular dependency 😞

The proposed fix by @wuservices to extract-chunks.js works, however since you're modifying the source of node_modules, this doesn't work across different developers sharing a repo.

Is there a better way to disable the preload-webpack-plugin? Or an update on when @vue/preload-webpack-plugin will be patched to resolve this issue?

@LinusBorg
Copy link
Member

THB no, thia got drowned out a bit. If someone was up for PR what would be welcomed.

@dalezak
Copy link

dalezak commented Jul 26, 2019

@LinusBorg I sent @wuservices's suggested fix as PR here vuejs/preload-webpack-plugin#3.

@LinusBorg
Copy link
Member

/cc @sodatea

@haoqunjiang
Copy link
Member

Fixed in @vue/preload-webpack-plugin v1.1.1

chochihim added a commit to measurabledatatoken/mymdt that referenced this issue Aug 28, 2019
2. "pages" option leads to vuejs/vue-cli#2463. Upgrade vue related packages to fix it
3. fix autoprefixer warning https://github.com/postcss/autoprefixer/releases/tag/9.6.0
4. draft dapp Data point rewards screen
vitaliimelnychukpyvud added a commit to vitaliimelnychukpyvud/joymikem that referenced this issue Oct 6, 2022
genie099 added a commit to genie099/ant-design-vue-pro that referenced this issue Nov 13, 2022
smartdev924 added a commit to smartdev924/ant-design-vue-pro that referenced this issue Apr 8, 2023
Watcher919 pushed a commit to Watcher919/Vue-antd that referenced this issue Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests