Vue-cli: "Cannot assign to read only property 'exports' of object '#<Object>'" when importing library

Created on 3 Oct 2018  ยท  9Comments  ยท  Source: vuejs/vue-cli

Version

3.0.4

Reproduction link

https://github.com/mrodal/vue-cli-lib-ts-error

Node and OS info

npm 6.4.1/node 10.11.0/Windows 10

Steps to reproduce

Create project to be a library with vue-cli. Options: just babel
Create entry file exporting the hello world component
Build library with vue-cli-service build --target lib --name lib index.js

Create host project. Options: just babel
npm install the library project
use an import statement importing the component

What is expected?

Import successfull

What is actually happening?

Cannot assign to read only property 'exports' of object '#<Object>'


I think it may be related to versions of webpack, vue libraries or something like that, because I have another project that I cannot share because its private, and there, the import works as expected.

In that project that works, if I remove node_modules and package-lock.json and install everything again, it stops working and the same error appears.

The new package-lock.json has different versions on the package's requires even if the package has the same version in both files...

needs team repro

Most helpful comment

I found the missing line that generates the problem:
image

packages/@vue/cli-service/lib/config/base.js:40:

    webpackConfig.resolve
      .set('symlinks', false) // this line was removed in 3.0.2
      .extensions
        .merge(['.js', '.jsx', '.vue', '.json'])

https://webpack.js.org/configuration/resolve/#resolve-symlinks

Solution/Workaround

Adding this to the webpack config in vue.config.js solves the issue

resolve: {
    symlinks: false
}

I dont know why it doesnt break when removing @vue/cli-plugin-babel though.

Here's the commit that introduced this change: https://github.com/vuejs/vue-cli/commit/c9cc22586662d28a754336a3c6c80b1ca0875570

Update

It fails with babel because when not using the symlink, babel doesnt exclude this library because the path that it receives isnt on node_modules
image

All 9 comments

Getting this issue as well.

Update: The problem seems to be related to @vue/cli-plugin-babel, if I remove it from package.json, the error disappears!

Update 2: The error is not present with @vue/cli-service 3.0.1 (even if I leave @vue/cli-plugin-babel in the package.json). It starts happening from @vue/cli-service 3.0.2 onward.

Update 3: The error is definitely in @vue/cli-service 3.0.2, I have all the other deps exactly on the same versions

I found the missing line that generates the problem:
image

packages/@vue/cli-service/lib/config/base.js:40:

    webpackConfig.resolve
      .set('symlinks', false) // this line was removed in 3.0.2
      .extensions
        .merge(['.js', '.jsx', '.vue', '.json'])

https://webpack.js.org/configuration/resolve/#resolve-symlinks

Solution/Workaround

Adding this to the webpack config in vue.config.js solves the issue

resolve: {
    symlinks: false
}

I dont know why it doesnt break when removing @vue/cli-plugin-babel though.

Here's the commit that introduced this change: https://github.com/vuejs/vue-cli/commit/c9cc22586662d28a754336a3c6c80b1ca0875570

Update

It fails with babel because when not using the symlink, babel doesnt exclude this library because the path that it receives isnt on node_modules
image

I think this is the expected behavior. symlinks option should only be explicitly disabled when you do know what you are doing โ€” after all, it is not the default setting of webpack (thus unintuitive, may also break some third party utilities).

I just ran into this issue as well and posted a comment about it here: https://github.com/webpack/webpack/issues/4039#issuecomment-460022779

Workaround:

Instead of fiddling with the symlinks option, move your libraries under a "fake"
node_modules directory that will match that final /node_modules/ regexp.

Using the example from @mrodal's screenshot, move the library under development from
C:\fractal\vue-cli-lib-ts-error -> C:\fractal\node_modules--dev\vue-cli-lib-ts-error

Then just link the library as normal and vue-cli/Webpack should correctly exclude that project (and any others under that directory) from transpilation.

I'm having the exact same issue with the vue-cli. I'm using:
"build-bundle": "vue-cli-service build --target lib --name moetje ./lib/index.js",

For my build script. My index looks like so:

import Moetje from './Moetje.vue'

function install(Vue, options) {
  Vue.component(options.name || 'Moetje', Moetje)
}

export { Moetje }
export default install

And the dist folder looks like this:

โ”œโ”€โ”€ demo.html
โ”œโ”€โ”€ moetje.common.js
โ”œโ”€โ”€ moetje.common.js.map
โ”œโ”€โ”€ moetje.umd.js
โ”œโ”€โ”€ moetje.umd.js.map
โ”œโ”€โ”€ moetje.umd.min.js
โ””โ”€โ”€ moetje.umd.min.js.map

0 directories, 7 files
--------------------------

The exact error is:
Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'. I was unable to fix this issue with the fixes above.

Vue cli version = 3.0.1

One thing that worked for me was telling babel to ignore my commonjs files, as they don't need to be transpiled.

babel.config.js

module.exports = {
  presets: [
    '@vue/app',
  ],
  ignore: [
      'src/entities/*'
  ]
}

App.vue

// commonjs import
const User = require('./entities/User');
// es6 module import
import Component from './components/Button.vue';

This may also help:
https://forum.vuejs.org/t/vue-cli-library-build-error-cannot-assign-to-read-only-property-exports-of-object-object/55492/3

When you're using module locally

  1. You need to use npm link.
  2. Disable symlink in vue.config.js in the project where you're importing this module.

Thanks @theharshin, running npm link solved my problem.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yyx990803 picture yyx990803  ยท  34Comments

lbicknese picture lbicknese  ยท  41Comments

deanilvincent picture deanilvincent  ยท  38Comments

dimavolo picture dimavolo  ยท  75Comments

AegirLeet picture AegirLeet  ยท  38Comments