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

Can't find module within modulesDirectories #2119

Closed
jeron-diovis opened this issue Feb 29, 2016 · 35 comments
Closed

Can't find module within modulesDirectories #2119

jeron-diovis opened this issue Feb 29, 2016 · 35 comments

Comments

@jeron-diovis
Copy link

webpack config:

resolve: {
    modulesDirectories: [
      "package_modules",
      "/path/to/app",
      "node_modules"
    ],
]

Option resolve.root is not defined.

Files tree:

/app
|- lib
|   \- index.js
|
\- my_package
      |- package_modules
      |     \- lib
      |          \- index.js
      |
      |- subfolder
      |     \- file_in_subfolder.js
      |
      \ - file_in_package.js

lib/index:
export const foo = "foo";

my_package/package_modules/lib/index:
export const bar = "bar";

my_package/file_in_package:

import * as obj from "lib";
console.log("lib in package root:", obj);

my_package/subfolder/file_in_subfolder:

import * as obj from "lib";
console.log("lib in package subfolder:", obj);

In console I have:

> lib in package root: { bar: "bar" }
> lib in package subfolder: { foo: "foo" }

Is it correct? I expected that it will be { bar: "bar" } in both cases.
Changing import path to lib/index does not help.

@sokra
Copy link
Member

sokra commented Feb 29, 2016

It is correct.

@jeron-diovis
Copy link
Author

So it works not exactly like node_modules does? I can't understand the logic.

@sokra
Copy link
Member

sokra commented Feb 29, 2016

modulesDirectories should not contain absolute paths. /path/to/app is wrong inside of moduleDirectories. /path/to/app should be inside of resolve.root or resolve.fallback.

@jeron-diovis
Copy link
Author

Ok, got it.

My idea was to achieve following resolution order: modulesDirectories => app root => node_modules (to ensure that node_modules never overrides local app modules). It seems that the most correct solution will be to create one more package_modules folder at app root.

@sokra
Copy link
Member

sokra commented Feb 29, 2016

It seems that the most correct solution will be to create one more package_modules folder at app root.

yep, that's the best solution with webpack 1.

with webpack 2 modulesDirectories root and fallback were merged into modules:

    modules: [
      "package_modules",
      "/path/to/app",
      "node_modules"
    ]

@jeron-diovis
Copy link
Author

Wow 👍
From this moment I'm waiting for stable webpack 2 release much more)

@jeron-diovis
Copy link
Author

Playing with webpack 2 (2.1.0-beta.4), I implemented files structure as in topic and modules config as you described above. It works brilliant.
Then, I renamed lib folder to constants folder everywhere in my files tree, and changed imports respectively.
And my build crashed with this:

ERROR in ./~/constants-browserify/constants.json
Module parse failed: /path/to/project/node_modules/constants-browserify/constants.json Unexpected token (2:12)
You may need an appropriate loader to handle this file type.
| {
|   "O_RDONLY": 0,
|   "O_WRONLY": 1,
|   "O_RDWR": 2,
 @ ./src/index.js 5:17-37

After some debugging, I found the rule: everything from node_modules with -browserify suffix takes precedence before local modules. tty, http, vm, stream – for all of this I see content from node_modules in my build file. For other node_modules – no, I tried several. Only *-browserify ones.

Please explain what's going on here.

@jeron-diovis jeron-diovis reopened this Mar 1, 2016
@jeron-diovis
Copy link
Author

Actually, same happens even with the most simple configuration.

/
|- src
|  |- index.js
|  \- constants.js
\- webpack.config.js

src/index.js:

console.log(require("constants"));

src/constants.js:

module.exports = { foo: "foo" };

webpack.config.js:

module.exports = {
    entry: "index.js",

    output: {
        filename: "build.js"
    },

    resolve: {
        modules: [
            __dirname + "/src"
        ]
    }
};

node_modules are not included to resolve.modules at all. And still build fails with

ERROR in ./~/constants-browserify/constants.json
Module parse failed: /path/to/app/node_modules/constants-browserify/constants.json Unexpected token (2:12)
You may need an appropriate loader to handle this file type.
| {
|   "O_RDONLY": 0,
|   "O_WRONLY": 1,
|   "O_RDWR": 2,
 @ ./src/index.js 1:12-32

@sokra
Copy link
Member

sokra commented Mar 7, 2016

add the json-loader

@jeron-diovis
Copy link
Author

How json-loader will prevent bundling external package constants-browserify instead of my local module src/constants.js?
That's the problem, not parsing json.

@eisisig
Copy link

eisisig commented Mar 8, 2016

constants-browserify is is trying to load /path/to/app/node_modules/constants-browserify/constants.json... And webpack doesn't understand that until you have the right loader for that file type (.json)... Just as if something was trying to load a *.lessor *.jpg file you would need loaders for those

That is not related to the first problem you posted. So I suggest installing json-loader to get past this

@jeron-diovis
Copy link
Author

@eisisig @sokra Once again: in this example webpack is configured to search for modules only in /path/to/app/src, and node_modules are not included at all. So require("constants") in app module must resolve to /path/to/app/src/constants.js, isn't it?
And, anyway, I don't require constants-browserify in my code, I require just constantswhy name
constants-browserify considered matching this request?

That is not related to the first problem you posted

Should I post this as separate issue?

@sqal
Copy link

sqal commented Apr 2, 2016

@jeron-diovis I have encountered exactly the same problem. It's weird that webpack tries to import node_modules/constants-browserify/constants.json and not constants/index.js from my app directory. When i change folder name from constants to whatever, it works as it should be. Did you perhaps solve your problem?

My webpack config:

const jsSrc = path.resolve(__dirname, 'src/app');

module.exports = {
  context: jsSrc,
  entry: {
    app: "./index.js",
    vendor: [
      "vue",
      "vue-router",
      "socket.io-client"
    ]
  },
  output: {
    filename: '[name].bundle.js',
    chunkFilename: '[name].[id].js'
  },
  resolve: {
    modules: [
      jsSrc,
      'node_modules'
    ],
    extensions: [
      '',
      '.js',
      '.json',
      '.vue'
    ],
  },
  externals: {
    Modernizr: 'Modernizr',
    TweenLite: 'TweenLite'
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: 'vendor.bundle.js',
      minChunks: Infinity
    }),
  ],
  module: {
    loaders: [
      {
        test: /\.vue$/,
        loader: 'vue'
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          cacheDirectory: true
        }
      }
    ]
  }
};

When i try to import something like that in my src/app/index.js

import { DEBUG } from 'constants'

that couses the error, but works when i use relative path:

import { DEBUG } from './constants'

@jeron-diovis
Copy link
Author

@sqal Nope, I have no idea what to do with this except of, yes, renaming the folder.
As I noticed above, it's reproducible not only for constants, but for all whatever-browserify modules.

So I'm just still waiting while @sokra come and explain us what's going on.

@bebraw
Copy link
Contributor

bebraw commented Dec 24, 2016

Can you try against current webpack 2 rc? It handles JSON now.

@valerybugakov
Copy link

@bebraw same issue here with webpack@2.2.1

@bebraw
Copy link
Contributor

bebraw commented Jan 31, 2017

@valerybugakov Any chance for a repository to study to confirm the issue?

@valerybugakov
Copy link

I can create one later today. But maybe you know a way to ignore this module in the client code?

@bebraw
Copy link
Contributor

bebraw commented Jan 31, 2017

@valerybugakov Ok. There are things like module.noParse, but I would need to see some code to say more.

@valerybugakov
Copy link

@bebraw Short version of what I have right now:

import { ENTITIES } from 'constants';

it's transpiled into

var _constants = __webpack_require__("./node_modules/constants-browserify/constants.json");

And webpack config:

// some imports and env stuff here...

module.exports = {
  stats,
  devServer: {
    stats,
    hotOnly: true,
    contentBase: path.join(__dirname, 'dev')
  },

  devtool: dev ? 'eval' : false,

  entry: [
    path.join(__dirname, '../index.web.js')
  ],

  output: {
    filename: 'bundle.js'
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [
          path.resolve(__dirname, '../src'),
          path.resolve(__dirname, '../node_modules/react-native-vector-icons'),
          path.resolve(__dirname, '../node_modules/react-native-drawer'),
          path.resolve(__dirname, '../node_modules/react-native-popup-dialog'),
          path.resolve(__dirname, '../node_modules/react-native-modalbox'),
          path.resolve(__dirname, '../node_modules/react-native-flip-card'),
          path.resolve(__dirname, '../node_modules/react-native-snap-carousel'),
        ],
        options: { cacheDirectory: true },
      },
      {
        test: /\.(gif|jpe?g|png|svg|tff)$/,
        loader: 'url-loader',
        options: { name: '[name].[hash:16].[ext]' }
      },
      {
        test: /\.ttf$/,
        loader: 'file-loader', // or directly file-loader
        include: [
          path.resolve(__dirname, '../node_modules/react-native-vector-icons'),
          path.resolve(__dirname, '../src/assets/icons'),
        ]
      },
      {
        test: /\.worker.js$/,
        loader: 'worker-loader',
        options: { inline: true }
      },
      {
        test: /\.glsl$/,
        loader: 'shader-loader'
      },
    ],
  },

  resolve: {
    extensions: ['.js', '.web.js'],
    alias: {
      'react-native': 'react-native-web',
    },
    modules: [
      path.resolve(__dirname, '../src'),
      path.resolve(__dirname, '../node_modules'),
    ],
  },

  plugins,
};

@valerybugakov
Copy link

  module: {
    noParse: /constants-browserify/,
  },

Didn't help :(
Got same the transpilation result.

@bebraw
Copy link
Contributor

bebraw commented Jan 31, 2017

@valerybugakov Why import { ENTITIES } from 'constants'; instead of import ENTITIES from 'constants'; or import * as ENTITIES from 'constants';?

@valerybugakov
Copy link

@bebraw actually there're more destructured variables import { ENTITIES, STICKY_CATEGORIES, ... } from 'constants';

@bebraw
Copy link
Contributor

bebraw commented Jan 31, 2017

@valerybugakov Ok, basically this feels like a JSON and ES6 module syntax specific problem. Could you open a separate issue with a little example we can run? You can also try the old require syntax to confirm. Perhaps some handling is missing.

@valerybugakov
Copy link

@bebraw Ok, let me try require.

@valerybugakov
Copy link

@bebraw no, same result:

const constants = require('constants')
// transpiled into
var constants = __webpack_require__("./node_modules/constants-browserify/constants.json");

@bebraw
Copy link
Contributor

bebraw commented Jan 31, 2017

@valerybugakov Ah... I understand better now. You basically want to inline the result (var constants = { ENTITIES: ..., STICKY_CATEGORIES: ... }), right? Importing might not be the way then. Look up solutions like DefinePlugin. You could perform a literal replacement like that through them.

@valerybugakov
Copy link

Lol, I found a workaround, but will open an issue with example later.

    alias: {
      'react-native': 'react-native-web',
      'constants': path.resolve(__dirname, '../src/constants'),
    },

@valerybugakov
Copy link

@bebraw I think DefinePlugin has a little bit different purpose, I use it to define environment variables. In constants.js I have lots of string/array exports (similar to Redux action types).

export const ENTITIES = ['some', 'entities', 'here', ...]
export const STICKY_CATEGORIES = [...]

@bebraw
Copy link
Contributor

bebraw commented Jan 31, 2017

@valerybugakov Yeah, DefinePlugin would be sketchier for sure. Reading back, maybe import { ... } from 'constants'; should have been import { ... } from 'browserify-constants';, but I'll know more after you open that issue.

@valerybugakov
Copy link

@bebraw yeah, will do that. Thanks for helping out :)

@valerybugakov
Copy link

@bebraw done

@jeron-diovis
Copy link
Author

What is the status of this issue?
Is this a final recommended solution?

@webpack-bot
Copy link
Contributor

This issue had no activity for at least half a year.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@webpack-bot
Copy link
Contributor

Issue was closed because of inactivity.

If you think this is still a valid issue, please file a new issue with additional information.

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

7 participants