Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

create a test entry point in webpack react application

tldr: I'm able to require everything to make the app run, but if I require modules from within a test (which is in the app - see dir structure below) file, the whole dependency chain breaks.

I'm having some difficulty require-ing components from my app/test directory (in my webpack React.js application) below that I have no difficulty require -ing from any other file in the /app folder. This is the directory structure

app
  /components/checkout.jsx
  /components/button.jsx
  /test/test.js 
  index.jsx  
dist
node_modules
webpack.config.js
package.json

in my webpack.config.js, I have it setup to use the jsx-loader for my React application like this

entry: {
   app: "./app/index"
},
module: {
   loaders: [
        {
             test: /\.jsx$/,
             loader: 'jsx-loader?insertPragma=React.DOM&harmony',
     }
  ]
},
resolve: {
 extensions: ['', '.js', '.jsx']
}

This allows me to require files ending in extension .jsx. For example, in /app/index.jsx I require /app/components/checkout.jsx by doing

 var Checkout = require('./components/Checkout')

And inside /app/components/checkout.jsx, I require the button

var Button = require('./components/Button')

so when I require the Checkout from the index.jsx, it handles the require of the Button without any problem.

However, from app/test/test.js, I do

var Checkout = require('../components/Checkout')

and webpack cannot find the Checkout component. When I view the tests in the webpack dev server, it doesn't show that the .jsx file extension was looked for. It searched

 app/components/Checkout
 app/components/Checkout.webpack.js
 app/components/Checkout.web.js
 app/components/Checkout.js
 app/components/Checkout.json

Therefore, I tried to use the jsx-loaderinline like this

 var Checkout = require(jsx-loader!'../components/Checkout')

from the test directory, and webpack can now find the file, but it throws an error saying that it cannot resolve the Button that Checkout requires. In other words, when I use the require from within the app/test folder, the whole dependency chain is thrown out of sync.

How can I change my webpack.config.js to be able to require application files in my tests with this directory structure, or, more generally, how to configure webpack to require an application file in a test?

Update

Project structure

/app
  /test/test.js
  /index.jsx
  /components/checkout.jsx (and button.jsx)
/dist
/node_modules
package.json
webpack.config.js

whole webpack config

var webpack = require('webpack');
module.exports = {
    context: __dirname + "/app",
    entry: {
      vendors: ["d3", "jquery"],
      app: "index"
      // app: "./app/index"

      },
    output: {
        path: './dist',
        filename: 'bundle.js', //this is the default name, so you can skip it
        //at this directory our bundle file will be available
        //make sure port 8090 is used when launching webpack-dev-server
        publicPath: 'http://localhost:8090/assets/'
    },

    externals: {
        //don't bundle the 'react' npm package with our bundle.js
        //but get it from a global 'React' variable

        'react': 'React'
        // 'd3': 'd3'
    },
    resolve: {
        modulesDirectories: ['app', 'node_modules'],
        extensions: ['', '.js', '.jsx'],
        resolveLoader: { fallback: __dirname + "/node_modules" },
        root: ['/app', '/test']
    },
    module: {
        loaders: [
            {
              test: /\.jsx$/, 
              loader: 'jsx-loader?insertPragma=React.DOM&harmony',
            }
        ]
    },

    plugins: [
    // definePlugin,
    new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js')

    ]
}
like image 545
Leahcim Avatar asked Jul 25 '15 23:07

Leahcim


3 Answers

One possible solution would be to always require with file extension:

var Checkout = require('./components/Checkout.jsx')
like image 187
Yevgen Safronov Avatar answered Nov 12 '22 12:11

Yevgen Safronov


I guess it may be cuz of setting "test" as a root directory. But it isn't clear untill you share your code. Can you gimme a link to GitHub repo or something?

like image 40
gyzerok Avatar answered Nov 12 '22 12:11

gyzerok


i see you are using the harmony parameter, can i assume u are using, es6?

If so i had this problem before, the problem for me was that the files where added, as es6 without beeing transformed, to es5 by jsx-loader / babel-loader.

so i needed to add:

preLoaders: [{
    test: [/\.jsx$/, /\.js$/],
    include: // modules here
    loaders: ['babel-loader?optional[]=runtime']
}]

but then it would not explain why this only fails for your tests. maybe u can elaborate on what is runned when u run your tests but for now im still under the assumption of you using es6,

if the above situation is not the case for you, try installing a local version of webpack, and look for it in your local dir, also for your app folder

(resolveLoader: { root: path.join(__dirname, "node_modules") })

hope this helps

edit: ps looking at your config, resolveLoader should not be a part of your resolve, in another webpack setup i use, i have the following setup for resolving:

resolve: {
  extensions: ['', '.js', '.jsx', '.json'],
  modulesDirectories: ['node_modules', 'node_modules/vl_tooling/node_modules']
},
resolveLoader: {
  modulesDirectories: ['node_modules', 'node_modules/vl_tooling/node_modules']
},
like image 3
Danillo Felixdaal Avatar answered Nov 12 '22 11:11

Danillo Felixdaal