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

error loading a .vue file from node_modules #678

Closed
tonypee opened this issue Feb 27, 2017 · 8 comments
Closed

error loading a .vue file from node_modules #678

tonypee opened this issue Feb 27, 2017 · 8 comments

Comments

@tonypee
Copy link

tonypee commented Feb 27, 2017

I am trying to share a 'common' library of my components between a few projects, and want to simply npm link another repo - then import from that module - eg: import 'common-fe/components/XX.vue'

I was expecting that this would just work, except it seems that it is erroring on my es7 features - in my bable.rc I use the legacy decorators. It seems that babel isnt using that preset for the files parsed in the node_module (only in the main project).

eg:

ERROR in ./~/babel-loader/lib!./~/vue-loader/lib/selector.js?type=script&index=0!../common-fe/components/Input.vue
Module build failed: SyntaxError: Unexpected token (29:0)

  27 | import Vue from 'vue'
  28 |
> 29 | @Component({
     | ^

If i add a bable.rc to the 'common' repo then i get other errors:

ERROR in ./~/babel-loader/lib!./~/vue-loader/lib/selector.js?type=script&index=0!../common-fe/components/Form.vue
Module build failed: ReferenceError: Unknown plugin "transform-runtime" specified in "/Users/tpee/repos/growlabs/common-fe/.babelrc" at 0, attempted to resolve relative to "/Users/tpee/repos/growlabs/common-fe"

i have npm installed the plugins in the common repo - but this doesnt help.

So, it seems that the code is being parsed as per the settings in the node_module?

I'd prefer not to have to compile the code to es5, should it be possible to use es6 like this?

@tonypee
Copy link
Author

tonypee commented Feb 27, 2017

Also, it seems that it isnt even converting es6 -> es5, the output is still es6 (not just breaking on es6+ features)

So, babel isnt actually converting the js for the script tag

@tonypee tonypee closed this as completed Feb 27, 2017
@tonypee tonypee reopened this Feb 27, 2017
@tonypee
Copy link
Author

tonypee commented Feb 27, 2017

node that in the babel setup i have a regex to not exclude the folder (maybe this is this issue.. but i think it should work):

{
        test: /\.js$/,
        loader: 'babel',
        include: projectRoot,
        exclude: /node_modules[.*|\/](?:(?!common-fe))/
      },

@tonypee
Copy link
Author

tonypee commented Feb 27, 2017 via email

@tonypee
Copy link
Author

tonypee commented Feb 27, 2017 via email

@yyx990803
Copy link
Member

This is more or less a Babel problem - the fact that it resolves .babelrc from the file's location is problematic, and I know they are considering changing that. Unfortunately, there's little we can do in vue-loader, your only option is probably explicitly setting babel-loader and its options in vue-loader options.

@laander
Copy link

laander commented Apr 10, 2018

For anyone else stumbling upon this issue, here's a short TLDR of the issue.

The problem

Sometime in Babel v7, the behaviour for resolving .babelrc inside node_modules when transpiling was changed. This means that modules that have published a .babelrc with e.g. the babel transform runtime plugin will hit a wall when building their bundle: ReferenceError: Unknown plugin "transform-runtime"

There is a great write-up and discussion here:
babel/babel#6766
And a proposed fix here (still up in the air):
babel/babel#7358

Affected Vue plugins

All these have a .babelrc in their project which is also published to npm (there's most likely a lot more):
phoenixwong/vue2-timepicker#34
ratiw/vuetable-2#41
shayneo/vue-fuse#15

Possible solutions

  1. As i understand it, Create React App have chosen to circumvent the .babelrc altogether and implement their own babel dependency graph: Compile dependencies with babel-preset-env facebook/create-react-app#3776

  2. Have the module maintainers remove .babelrc to the npm published module by adding it to their .npmignore.

  3. Downgrade to Babel v6 or wait for v7 to be officially released.

  4. Install the needed babel plugins/requirements in your local project, like:

npm install babel-plugin-transform-runtime --save-dev
npm install babel-preset-stage-2 --save-dev
npm install babel-preset-es2015 --save-dev

Do note that this might include the transform-runtime helper into your built bundle which should be unnecessary if your pretranspiling your bundle at built-time (the default approach with vue-cli v3). Smelly.

@jeppebemad
Copy link

jeppebemad commented May 28, 2018

I've managed to get around my similar issues by specifically telling webpack where to resolve modules and loaders, and also by resolving the babel-presets and plugins at at runtime.

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

and in module.exports..

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src'),
      'vue$': 'vue/dist/vue.esm.js'
    },
    modules: [resolve('node_modules')]
  },
  resolveLoader: {
    modules: [resolve('node_modules')]
},

Now load the babelrc file and resolve the full paths at runtime, and include the source-code path:


const fs = require('fs')
const babelConfig = JSON.parse(fs.readFileSync('.babelrc'))

..

{
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        include: [resolve('src'), resolve('../../shared'), resolve('node_modules/webpack-dev-server/client')],
        options: {
          presets: babelConfig.presets.map(preset => {
            if (typeof(preset) === 'string') return require.resolve(`babel-preset-${preset}`)
            else return [require.resolve(`babel-preset-${preset[0]}`), preset[1]]
          }),
          plugins: babelConfig.plugins.map(plugin => require.resolve(`babel-plugin-${plugin}`)),
        }
      },

The preset/plugin part I got from this issue

@jmkenz
Copy link

jmkenz commented Jan 7, 2020

Thanks @laander and @jeppebemad! I found that the existence of a .babelrc file in my targeted node_modules sub-directory made no difference. Even when there was no .babelrc file there at all, the directory was not getting transpiled. The good news is that specifying babel config options directly in my webpack config file did fix this problem! For me, I just deleted the .babelrc file from my main application repo and specified all my options right in the webpack config file.

{
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules\/(?!(@pegex\/frontend-shared)).*/,
        options: { // we are required to specify options this way instead of .babelrc to be able to include projects in node_modules
          presets: [
            ['@babel/preset-env']
          ],
          plugins: ['@babel/plugin-transform-runtime'],
          env: {
            test: {
              plugins: ['istanbul']
            }
          }
        }
      },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants