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

Doesn't compile a npm linked module #149

Closed
acnovais opened this issue Nov 11, 2015 · 72 comments
Closed

Doesn't compile a npm linked module #149

acnovais opened this issue Nov 11, 2015 · 72 comments

Comments

@acnovais
Copy link

Not sure this is a babel loader issue or a webpack issue.

I am developing two modules and one of them has a dependency on the other. So I have npm linked it.
I have the following config on webpack:

loaders: [{
      test: /\.js$/,
      loaders: ['babel'],
      exclude: /node_modules\/(?!other-module)/,
      include: __dirname
}]

This works fine if I install dependency as a local dependency but if I use npm link, babel doesn't process it.

Am I missing something? Or is there a workaround for this?

@acnovais acnovais changed the title Doesn't compile a npm link Doesn't compile a npm linked module Nov 11, 2015
@cdaringe
Copy link

interesting, I just ran into this issue as well. however, i did unlink, make a copy, clear my node modules, and retry in the copy, with no results. unsure at this point. will continue to debug

@scriptjs
Copy link

Your config is not right. You need to include babel presets in your loader config as well as your babelrc or babelConfig in your package.json. The presets for babel loader can be added with query params or query object. Review the babel 6 docs on presets for your babel config. The preset packages must also be included your project. Currently things are working for me with babel-loader@6.01 with babel presets and babel-core@6.1.4

@cdaringe
Copy link

perhaps you're right. I never installed all of the deps. Likely part of a major bump? Readme ref

@henit
Copy link

henit commented Nov 26, 2015

I have the same issue. I have a package at /path/to/project/ and a dependency that worked well when located in /path/to/project/node_modules/dependency/. However, when I npm link the dependency to a git clone located at the same place as the project (/path/to/dependency/, linked via /usr/lib/node_modules the way npm links), then the loaders complain that there is no presets installed in the package directory for dependency when I run webpack from the project directory that npm links to it.

Webpack loader config in /path/to/project:

{
    test: /\.jsx?$/,
    loader: "babel-loader",
    query: {
        presets: ["es2015", "react"]
    }
}

Output from running webpack:

ERROR in ../dependency/index.js
Module build failed: Error: Couldn't find preset "es2015" relative to directory "/path/to/dependency"

How can I make babel-loader use the presets installed in the project the same way it did when the dependency where located inside the project directory instead of looking for it in the linked project directory?

@scriptjs
Copy link

@henit Try putting the presets in your package.json instead with a babel property:

  "babel": {
    "presets": [
      "es2015",
      "react"
    ]
  },

@henit
Copy link

henit commented Nov 26, 2015

@scriptjs Gave the same webpack error as in my post above

Having the presets in neither the loader config or directly in the webpack config makes it complain about the syntax (since the file it is trying to include is in ES6). Once I include the presets in one of the two places, the syntax error is replaced by complaining that it does not find the preset modules. Whatever I do, I cannot get the loader to use the presets from the current project modules when importing files from a dependency that is located outside of the root of the package (since I have put the npm linked module in the directory above as described earlier).

I tried adding the resolve.fallback with the parent dir (where the linked dependency is located), did not help.

@scriptjs
Copy link

@henrit Perhaps there is something not sane in your babel dependencies impacting your project but you will need to investigate this. I am faced with something just about as strange. This is having an impact on a react native app project in a monorepo. If I remove the project out of the monorepo it compiles and runs. Within the monorepo it compiles but will not run due to an exception being thrown in react native since there is something global leaking into it from babel – from where is the question – and it is bugging the hell out of me. I too take advantage of npm link in this work.

There are a lot of moving parts atm. React, babel, npm are all moving simultaneously at a significant speed which only makes getting to the bottom of these things more difficult.

@Swaagie
Copy link

Swaagie commented Dec 14, 2015

Seeing the same issue, building failed with an npm link module, after removing the link and manually copying over the locally developed module it worked fine. There is something odd with symlinks going on. Webpack config is as follow. Working with node@4.2 and npm@3.5.

'use strict';

const path = require('path');
const ucfirst = require('ucfirst');
const component = path.basename(process.env.COMPONENT);

module.exports = {
  entry: path.join(__dirname, component, 'index.jsx'),
  output: {
    filename: path.join(__dirname, component, 'dist', 'index.js'),
    library: 'UX' + ucfirst(component),
    libraryTarget: 'umd'
  },
  externals: {
    'prismjs': 'Prism',
    'react': 'React',
    'react-dom': 'ReactDOM'
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      loader: 'babel-loader?presets[]=react,presets[]=es2015'
    }, {
      test: /\-example\.jsx?$/,
      loader: 'raw-loader'
    }]
  }
};

@Swaagie
Copy link

Swaagie commented Dec 18, 2015

I'm pretty sure I've got those modules installed and it's not about the presets, babel-loader simply fails with symlinks

@skipjack
Copy link

Yea I agree with @Swaagie. The babel-loader fails to find it's preset modules when the module isn't under the project root containing the node_modules (even when resolveLoader.root is set). Similar to #166

@nirazul
Copy link

nirazul commented Dec 20, 2015

I can confirm that this has something to do with the location of the presets package.
My setup consists of two node_modules folders. One for a node-server and one for the frontend-build, which relies partially on webpack and webpack-stream.

<project-root>
    /node_modules
    /frontend
        /node_modules

I've first tried to use es2015 presets install dependency in the nested frontend folder. I've ended up getting the same error message as some others here:

ModuleBuildError: Module build failed: Error: Couldn't find preset "es2015" relative to directory "path/to/jsmainfile"

When installing it in the node_modules folder of the project root, it magically works. This made no sense to me, as babel-core as well as babel-loader and webpack are not installed within this folder.

So there must be something wrong with either the webpack option resolveLoader.root or babel-loader loading mechanism (or both).

@mqklin
Copy link

mqklin commented Jan 3, 2016

@barroudjo
Copy link

Thanks @mqklin, this works, but unfortunately when you use multiple loaders you can't use a query object. Here is the workaround in this case:

var queryObject = {presets: [require.resolve('babel-preset-es2015')]};
var query = require('querystring').stringify(queryObject);
config.loaders = [{
    test: /\.js$/,
    loaders: ['ng-annotate', 'babel?' + query]
}];

@graup
Copy link

graup commented Jan 9, 2016

I have the same setup as @nirazul. Using require.resolve('babel-preset-es2015') instead of 'es2015' resolves this issue for me.

Additionally I set resolve.modulesDirectories: [path.resolve('./node_modules')] so modules in other directories can find modules installed in the main project.

@barroudjo
Copy link

An update on this issue: while this workaround works for most babel presets, it doesn't work for babel-transform-runtime, i.e. setting up the loader with:

query: {
    presets: [require.resolve('babel-preset-es2015')],
    plugins: [require.resolve('babel-plugin-transform-runtime')]
}

doesn't work. Has anyone found a workaround for symlinks and babel-transform-runtime ?

@jbcpollak
Copy link

same problem for me, this workaround seemed to help:

The query-stringify solution seems to have helped for me.

@ChrisRus
Copy link

Chiming in on this thread as I've got a variant scenario (I think). I've developing a CLI tool that functions like a black box site generator. My intent is that the tool be installed globally and executed from the command line where it locates a containing package.json relative to cwd() that it parses to retrieve some options. Subsequently, the contents of the target project (i.e. the dir structure rooted at the directory where package.json was found) is processed into a site, and the generated resources are written back out to the target project directory structure.

Internal to the tool, I synthesize webpack configuration objects and delegate to webpack which in turn delegates to babel-loader, babel ... and fails when resolving the es2015 and react presets as described here (for slightly different reasons than typical but same root cause I think).

Currently, webpack and babel loader are correctly resolved in the node_modules dir of my tool where they're declared as regular dependencies in the tool's package.json. This isn't a global install of anything more than a random Node.js derived CLI tool that happens to depend on webpack, babel... as an implementation detail.

So although I agree with the rationale of wanting to install babel on a per-project basis, this sharp edge with presets makes it difficult to embed in automation scripts.

For now I've modifying the dev-dependencies of the target project package.json and going to force an npm install prior to the first invocation of webpack (occurs as one of many steps in the site generation process encapsulated by the tool). But I think this extra complexity is not really necessary.

This thread: https://discuss.babeljs.io/t/error-parsing-jsx-with-global-installation-babel-preset-react/59/14 on Babel discussion is fairly recent and seems related.

Anyone know how to get this sort of wholly encapsulated embedding to work elegantly? Thanks.

@tlrobinson
Copy link

This is happening to me as as well. @barroudjo's suggested workaround seems to work in my case:

var BABEL_CONFIG = {
    cacheDirectory: true,
    presets: [
        "es2015",
        "stage-0",
        "react"
    ].map(function(name) { return require.resolve("babel-preset-"+name) }),
    plugins: [
        "transform-decorators-legacy"
    ].map(function(name) { return require.resolve("babel-plugin-"+name) })
};

@dnutels
Copy link

dnutels commented Mar 11, 2016

@tlrobinson

I don't think it does. At least in my case this solution caused the presets to be packaged with the source code.

Have you checked yours?

P.S.

Actually, I don't know if that's what caused that... but when doing either:

  1. resolve.alias for a specific module (outside of the "normal" tree)
  2. above solution with presets

resulting bundle includes stuff like:

/* WEBPACK VAR INJECTION */(function(process) {/**
     * Copyright (c) 2013-present, Facebook, Inc.
     * All rights reserved.
     *
     * This source code is licensed under the BSD-style license found in the
     * LICENSE file in the root directory of this source tree. An additional grant
     * of patent rights can be found in the PATENTS file in the same directory.
     *
     */

    'use strict';

    /**
     * Use invariant() to assert state which your program assumes to be true.
     *
     * Provide sprintf-style format (only %s is supported) and arguments
     * to provide information about what broke and what you were
     * expecting.
     *
     * The invariant message will be stripped in production, but the invariant
     * will remain to ensure logic does not differ in production.
     */

    function invariant(condition, format, a, b, c, d, e, f) {
      if (process.env.NODE_ENV !== 'production') {
        if (format === undefined) {
          throw new Error('invariant requires an error message argument');
        }
      }

@skipjack
Copy link

I'm a big fan of @seantimm's solution in #179:

const babelSettings = {
  extends: path.join(__dirname, '/.babelrc')
}

...

loader: 'babel?' + JSON.stringify(babelSettings)

Easier than all those require.resolves and allows you to decouple your settings into the .babelrc again. Just thought I'd add it as another solution until @Swaagie's PR is merged in Babel...

@Swaagie
Copy link

Swaagie commented Mar 22, 2016

Added tests to the PR few days ago (finally), I'll see if I can give someone a nudge.

@Jokcy
Copy link

Jokcy commented Mar 29, 2016

@scriptjs I guess you are right. My project ran into this error in my mac but everything is ok on my firend's mac, and the difference is he never us react native. And my Solution is using a .babelrc file to config babel not in webpack config file. I guess babel will search for .babelrc file if project folder not contain one

@xsbchen
Copy link

xsbchen commented Apr 1, 2016

It's work for me, thank you @scriptjs

@IstoraMandiri
Copy link

I still can't get this to work. I've tried everything in this thread. Seems to be specific with npm linkd react components. ES6 appears to be working, but it's choking as soon as it gets to jsx including in a linked module.

ERROR in ../myComponent/src/test.js
Module parse failed: /Users/chris/code/myComponent/src/test.js Unexpected token (6:6)
You may need an appropriate loader to handle this file type.
    "babel-core": "^6.9.0",
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-2": "^6.5.0",

@Swaagie
Copy link

Swaagie commented May 30, 2016

@hitchcott that's something else since the loaders are found, this might be the order of your loaders? Hard to tell without the config, don't hijack this issue though ;)

@mick-feller
Copy link

mick-feller commented Feb 14, 2018

Just want to give my 2 cents as well, at first the symlinks: false didn't work for me.

After some more digging i saw that in the resolve section i had the following setup:

resolve: {
        alias: {
             someAlias: 'alias path'
        },
        modules: [
            path.resolve(__dirname, '/app'),
            path.resolve('node_modules')
        ],
        symlinks: false
}

turns out that there is a big difference between absolute path loading in modules in the resolve section vs relative loading see this article: https://webpack.js.org/configuration/resolve/#resolve-modules

So with that setup it failed my build since it couldn't find the actual files in my symlinked directory.

After changing it to:

resolve: {
        alias: {
             someAlias: 'alias path'
        },
        modules: [
            path.resolve(__dirname, '/app'),
            'node_modules'
        ],
        symlinks: false
}

it worked perfectly for me, even my webpack dev server picks up the changes and refreshes what it needs to do.

Maybe it helps for someone who runs into this.

The reason why i'm adding my app to resolve modules is so i can reference pretty much anything from root level, so in my bundles i don't have to do:

../../someModule/index.js

instead i can just simply:

someModule/index.js

in case someone is wondering why i use that setting

@iwarner
Copy link

iwarner commented Mar 6, 2018

Using Webpack 4 I did not use the symlink: false in resolve

but simply had to use

    include: [
      fs.realpathSync('node_modules/component')
    ]

@jdpigeon
Copy link

jdpigeon commented Apr 5, 2018

For some reason, over the last couple months the exclude solution stopped working for me. The fix was simply to switch exclude to include!

include: /node_modules\/(?!module-name)/

@n8agrin
Copy link

n8agrin commented Jul 20, 2018

@coomysky's approach worked for me. #149 (comment)

@loganfsmyth
Copy link
Member

The issue here is most likely that .babelrc files in Babel 6 only apply to files nested in folders within the .babelrc's folder. This means the only option in Babel 6 is to put the configuration directly in your webpack.config.js.

As of Babel 7, this is restricted even further, and .babelrc files will also not apply to child packages, but we've also added support for project-wide babel.config.js files, so I'd recommend users who wish to compile node_modules and linked packages use those.

@ralyodio
Copy link

What should I put in babel.config.js?

shaun554 added a commit to shaun554/react-boilerplate that referenced this issue Mar 21, 2019
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
tijme added a commit to NorthwaveSecurity/forked-frida-inject that referenced this issue Apr 6, 2020
@MrCoder
Copy link

MrCoder commented Feb 2, 2021

What should I put in babel.config.js?

I had a .babel.rc at the project root folder. I just renamed it to babel.config.js and that fixed the problem. Within the file it has:

{
    "presets": [ 
        ["preact-cli/babel", { "modules": "commonjs" }]
    ]
}

jrand0m pushed a commit to jrand0m/fashcrowdapp that referenced this issue Aug 17, 2021
mauricewells pushed a commit to mauricewells/react-boilerplate that referenced this issue Jan 21, 2022
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
kazuma512 added a commit to kazuma512/react-boilerplate-typescript that referenced this issue Jun 2, 2023
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
AIDevMonster added a commit to AIDevMonster/react-boilerplate that referenced this issue Jun 21, 2023
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
whiteghostDev added a commit to whiteghostDev/react-boilerplate that referenced this issue Aug 6, 2023
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
muscliary pushed a commit to muscliary/react-boilerplate that referenced this issue Sep 12, 2023
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
wesleywang4766 added a commit to wesleywang4766/lodash that referenced this issue Mar 8, 2024
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
winder9 pushed a commit to M-Killer-dev/React-project that referenced this issue Jun 16, 2024
* fix(internals): Fix babel relative preset

Fix webpack issue with relative babel preset paths:
babel/babel-loader#149

* feat(docs): Add docs for extracting components

Add draft version of docs describing how to extract components to their own
npm packages.
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