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

Cannot read property 'isCE' of null in remote component with slot using Module Federation #4344

Closed
fatawesome opened this issue Aug 15, 2021 · 32 comments

Comments

@fatawesome
Copy link

Version

3.2.2

Reproduction link

https://github.com/fatawesome/vue-next-isce-issue

Steps to reproduce

Clone the repository, from root run yarn && lerna bootstrap && yarn start.
Navigate to http://localhost:3000.

What is expected?

On the page you should see two lines of text:

  1. Host content
  2. test remote component

What is actually happening?

Server crashes on renderSlot function with Cannot read property 'isCE' of null error.


Removing slot from remote component fixes the issue, but obviously we need slots in our code :)
Issue appears when building application on Module Federation architecture. We also use @telenko/node-mf package to fetch code in a universal manner, but I believe this lib cannot be a problem.

@LinusBorg
Copy link
Member

LinusBorg commented Aug 15, 2021

That's because you have two distinct copies of the Vue package being used, one in each package.

Vue uses a global singleton to track the current rendering instance - having more than one copy included will inevitably lead to such issues.

Solution: configure project in a way that Al packages use that same package.

In yarn workspaces, this would work fine because Vue would be hoistws to the root's node_modules.

@fatawesome
Copy link
Author

Sounds legit, thanks!
I will try messing with Module Federation configs (maybe forgot to mark package as singleton or smth) and let know if it helped.

@fatawesome
Copy link
Author

Yep, that definitely helped. Thank you @LinusBorg :)

@lonczynski
Copy link

@fatawesome could you please tell us what was the solution? I am facing the same problem and I don't know how to not conflict the two distinct copies of the Vue package. Thanks

@chirpycora
Copy link

Same here; I have not found a way to work around this issue. I made sure that both packages were using the same Vue version (matching versions and hashes in their package-lock.json files) and the 'isCE' of null error is still persisting. I also tried disabling symlink resolution for node_modules, and that had no effect either.

@mszkb
Copy link

mszkb commented Aug 28, 2021

Got the same issue. With vue 2 everything worked fine.
Adding my external library components with for example npm link and using in my external component I'll get
runtime-core.esm-bundler.js Uncaught TypeError: Cannot read property 'isCE' of null

Versions of vue and any other dependencies are exact the same and I use npm atm.

@ghost
Copy link

ghost commented Sep 3, 2021

Using the npm link is the primary reason as the host application would try to use the vue from the linked library. Add these two lines to the vue.config.js of the host application.

  chainWebpack(config) {
    config.resolve.symlinks(false)
    config.resolve.alias.set( 'vue', path.resolve('./node_modules/vue'))    
  },  

Refer to: #2064 (comment)

@Jcanno
Copy link

Jcanno commented Sep 16, 2021

use webpack resolve vue to one package reference.

@rhmkstk
Copy link

rhmkstk commented Dec 8, 2021

Hi,

I am building a library with vue3 and vite, when i use the library if i use slot i got same issue, i tried the solutions in this thread but i can not fix the issue.

error: Uncaught TypeError: Cannot read properties of null (reading 'isCE')

My vite config.js:

import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import eslintPlugin from 'vite-plugin-eslint'
const path = require('path')

export default defineConfig({
  resolve: {
    alias:{
      '/@': path.resolve('./node_modules/vue')
    },
    preserveSymlinks: false
  },
  plugins: [
    eslintPlugin(),
    vue(),
  ],
  build: {
    lib: {
      entry: path.resolve(__dirname, './src/components/main.js'),
      name: 'LuiVue',
      fileName: (format) => `lui-vue.${format}.js`
    },
  },
  rollupOptions: {
    external: ['vue'],
    output: {
      globals: {
        vue: 'Vue',
      },
    },
  },
})

@ejirocodes
Copy link

Hi,

I am building a library with vue3 and vite, when i use the library if i use slot i got same issue, i tried the solutions in this thread but i can not fix the issue.

error: Uncaught TypeError: Cannot read properties of null (reading 'isCE')

My vite config.js:

import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import eslintPlugin from 'vite-plugin-eslint'
const path = require('path')

export default defineConfig({
  resolve: {
    alias:{
      '/@': path.resolve('./node_modules/vue')
    },
    preserveSymlinks: false
  },
  plugins: [
    eslintPlugin(),
    vue(),
  ],
  build: {
    lib: {
      entry: path.resolve(__dirname, './src/components/main.js'),
      name: 'LuiVue',
      fileName: (format) => `lui-vue.${format}.js`
    },
  },
  rollupOptions: {
    external: ['vue'],
    output: {
      globals: {
        vue: 'Vue',
      },
    },
  },
})

@rhmkstk add this to your vite.config.ts

resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) }, dedupe: ['vue'], // this line }

@tangjiahui-cn
Copy link

if you build with rollup. please add "external: ["vue"]" in build config file.like this:
export default { ... external: [ "vue" ], ... }

@941477276
Copy link

Hi,
I am building a library with vue3 and vite, when i use the library if i use slot i got same issue, i tried the solutions in this thread but i can not fix the issue.
error: Uncaught TypeError: Cannot read properties of null (reading 'isCE')
My vite config.js:

import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import eslintPlugin from 'vite-plugin-eslint'
const path = require('path')

export default defineConfig({
  resolve: {
    alias:{
      '/@': path.resolve('./node_modules/vue')
    },
    preserveSymlinks: false
  },
  plugins: [
    eslintPlugin(),
    vue(),
  ],
  build: {
    lib: {
      entry: path.resolve(__dirname, './src/components/main.js'),
      name: 'LuiVue',
      fileName: (format) => `lui-vue.${format}.js`
    },
  },
  rollupOptions: {
    external: ['vue'],
    output: {
      globals: {
        vue: 'Vue',
      },
    },
  },
})

@rhmkstk add this to your vite.config.ts

resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) }, dedupe: ['vue'], // this line }

did you solve this problem?

@tangjiahui-cn
Copy link

Hi,
I am building a library with vue3 and vite, when i use the library if i use slot i got same issue, i tried the solutions in this thread but i can not fix the issue.
error: Uncaught TypeError: Cannot read properties of null (reading 'isCE')
My vite config.js:

import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import eslintPlugin from 'vite-plugin-eslint'
const path = require('path')

export default defineConfig({
  resolve: {
    alias:{
      '/@': path.resolve('./node_modules/vue')
    },
    preserveSymlinks: false
  },
  plugins: [
    eslintPlugin(),
    vue(),
  ],
  build: {
    lib: {
      entry: path.resolve(__dirname, './src/components/main.js'),
      name: 'LuiVue',
      fileName: (format) => `lui-vue.${format}.js`
    },
  },
  rollupOptions: {
    external: ['vue'],
    output: {
      globals: {
        vue: 'Vue',
      },
    },
  },
})

@rhmkstk add this to your vite.config.ts
resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) }, dedupe: ['vue'], // this line }

did you solve this problem?

I have 2 ideas that you can try.

(1) config vite ssr。 like this:
export default defineConfig({...., ssr:{external: ["vue"]} ,.....}).
vite

(2)or, write a single file to use rollup build.
export default packagesInfo.map(({name: packageName}) => { return { input: getInput(packageName), output: ["umd", "es"].map((format) => ({ format, name: getName(packageName, format), file: getFile(packageName, format), globals: { vue: "vue" } })), plugins: [ typescript({ module: "ESNext" }), resolve(), aliasResolve(alias), // fixCE(), json(), vuePlugin(), babel({ extensions: [...DEFAULT_EXTENSIONS, "ts", "tsx"], babelHelpers: "bundled", exclude: "node_modules/**" }), postcss({ minimize: true, extract: "index.css", extensions: [".css", ".less", ".scss"] }), terser() ], external: ["vue"] } })
rollup.lib.js

@rhmkstk
Copy link

rhmkstk commented Feb 22, 2022

Hello,

thanks for your answer, after i try several solution i reintall project with newer vite version and it fix the issue

@mszkb
Copy link

mszkb commented Feb 26, 2022

Using the npm link is the primary reason as the host application would try to use the vue from the linked library. Add these two lines to the vue.config.js of the host application.

  chainWebpack(config) {
    config.resolve.symlinks(false)
    config.resolve.alias.set( 'vue', path.resolve('./node_modules/vue'))    
  },  

Refer to: #2064 (comment)

After revising the same issue this week, this actual resolved the issue in a component-library and npm link scenario

@webarthur
Copy link

Adding the dedupe: ['vue'] to my vite.config.js solve the problem. Thanks!

@uoau
Copy link

uoau commented Mar 7, 2022

Hi,
I am building a library with vue3 and vite, when i use the library if i use slot i got same issue, i tried the solutions in this thread but i can not fix the issue.
error: Uncaught TypeError: Cannot read properties of null (reading 'isCE')
My vite config.js:

import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import eslintPlugin from 'vite-plugin-eslint'
const path = require('path')

export default defineConfig({
  resolve: {
    alias:{
      '/@': path.resolve('./node_modules/vue')
    },
    preserveSymlinks: false
  },
  plugins: [
    eslintPlugin(),
    vue(),
  ],
  build: {
    lib: {
      entry: path.resolve(__dirname, './src/components/main.js'),
      name: 'LuiVue',
      fileName: (format) => `lui-vue.${format}.js`
    },
  },
  rollupOptions: {
    external: ['vue'],
    output: {
      globals: {
        vue: 'Vue',
      },
    },
  },
})

@rhmkstk add this to your vite.config.ts
resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) }, dedupe: ['vue'], // this line }

did you solve this problem?

I solved.

image

@linuschinsay
Copy link

use webpack resolve vue to one package reference.

how do I do that?

@huntJs
Copy link

huntJs commented Jun 5, 2022

I also met the same issue, the parent Application(vue3+vite2.0) share some common component to child Application, but if the common component exist slot , the child Application will throw an exception( vue3+ webpack5),
image
In parent Application, i had config below
image

so who can help me to slove this problem

@MaxLeiter
Copy link

@huntJs I have the same exact problem, so please report back if you make progress

@cheny-github
Copy link

nice dude

@xu-Aurora
Copy link

I also met the same issue, the parent Application(vue3+vite2.0) share some common component to child Application, but if the common component exist slot , the child Application will throw an exception( vue3+ webpack5), image In parent Application, i had config below image

so who can help me to slove this problem

I have the same problem, did you solve it?

@941477276
Copy link

I also met the same issue, the parent Application(vue3+vite2.0) share some common component to child Application, but if the common component exist slot , the child Application will throw an exception( vue3+ webpack5), image In parent Application, i had config below image
so who can help me to slove this problem

I have the same problem, did you solve it?

Just remove vue from dependencies in package.json in your public component library and add vue dependencies in devDependencies

@bneeland
Copy link

bneeland commented Jul 11, 2022

I had this issue when trying to build a vue3 project with a library imported as a submodule.

I solved this by:

  • Deleting yarn.lock files from both root project and submodule
  • Deleting node_modules from both root project and submodule
  • Deleting dist directory from both root project and submodule
  • Moving Vue to a dev dependency in package.json within my submodule (I had Vue set as a dependency in my submodule)
  • Setting the vue versions in both root project and submodule as exactly the same verison (3.2.37 in my case)
  • Adding ['vue'] to resolve.dedupe to my vite.config.js file in the root project. For completeness, here is my vite config file:
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    dedupe: ['vue']
  },
})
  • Running yarn install then yarn build in both root project and submodule

Then my submodule components used in my root project worked without this error.

Maybe all these steps weren't necessarily needed; I would be interested to know if I my solution could be improved.

@Eug620
Copy link

Eug620 commented Aug 31, 2022

Brother, have you solved it? The micro front end I tested also encountered this problem. When the father and son are vite + vue3 first load no problem, the switch encountered this situation, if you finally solve it, please tell me

@Rusinas
Copy link

Rusinas commented Dec 20, 2022

Same problem with custom UI library built with Vite and Vue 3 which I'm trying to use in my Nuxt app. The error is in the component which uses onMounted() hook:

[Vue warn]: onMounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.

[Vue warn]: onBeforeUnmount is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.

[Vue warn]: Unhandled error during execution of render function                                                                                   00:00:45  
  at <Dropdown dropdown-max-height=300 dropdown-min-width=60 disabled=false >
[nitro] [dev] [unhandledRejection] TypeError: Cannot read properties of null (reading 'isCE')    

Maybe this warns are not related, but when I don't import this exact component, everything is fine.

None of the solutions above helps :(

@flozero
Copy link

flozero commented Jan 29, 2023

why this has been closed even if the error happen all the time ? we should have hard tests on that as it seems people have it a lot when using module federation or library components

none of the solutions works unfortunately with latest vue version + vite 4

@tangjiahui-cn
Copy link

components

'isCE' happen because which has two differece vue verdion. you can try use 'external' to exclude another vue in components.

@zongzi531
Copy link

why this has been closed even if the error happen all the time ? we should have hard tests on that as it seems people have it a lot when using module federation or library components

none of the solutions works unfortunately with latest vue version + vite 4

@flozero You can try this config set at vue@3.2.x and vite@4

{
  resolve: {
    alias: {
      vue: path.resolve('your current vue folder', 'dist', 'vue.runtime.esm-bundler.js')
    }
  }
}

I am set this config solved my problem.

@razorness
Copy link

Take care what internal method from @vue/core you are using. In my case, I used the helper renderSlot() which not only bloated the bundle size of my lib by 50 kb but also caused this error.

@lisilinhart
Copy link

For me the error disappeared when I installed the dependency in the root project with npm instead of yarn. I also setup the lib similar to this vite configuration (https://github.com/ferryanggriawan/vue3-plugin-boilerplate/blob/master/vite.config.ts) and tried all the things recommended on this thread, but really only switching to npm on the installation made the error disappear.

@lt216
Copy link

lt216 commented Aug 24, 2023

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import path from "path";

// https://vitejs.dev/config/
export default defineConfig({
	resolve: {
		alias: {
			packages: path.resolve(__dirname, "packages"),
			examples: path.resolve(__dirname, "examples"),
			mixins: path.resolve(__dirname, "mixins"),
		},
	},
	build: {
		//打包后文件目录
		outDir: "lib",
		//压缩
		minify: false,
		lib: {
			entry: path.resolve(__dirname, "/packages/index.js"),

			formats: ["es"],
			name: "index",
			fileName: "index",
		},
		rollupOptions: {
			external: ["vue"],
			// resolve: {
			// 	dedupe: ["vue"],
			// },
			output: {
				globals: {
					vue: "Vue",
				},
			},
		},
	},
	plugins: [
		vue(),
		AutoImport({
			resolvers: [ElementPlusResolver()],
		}),
		Components({
			resolvers: [ElementPlusResolver({ importStyle: "sass" })],
		}),
	],
	css: {
		preprocessorOptions: {
			scss: {
				additionalData: `@use "./styles/element/index.scss" as *;`,
			},
		},
	},
});

解决了嘛 我是这样写的还是报错

Cannot read properties of null (reading 'isCE')
TypeError: Cannot read properties of null (reading 'isCE')

@github-actions github-actions bot locked and limited conversation to collaborators Sep 8, 2023
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