mzgoddard / jest-webpack

Use jest with webpack.
https://www.npmjs.com/package/jest-webpack
92 stars 21 forks source link

TypeError: Cannot read property 'endsWith' of undefined #16

Open thekevinbrown opened 7 years ago

thekevinbrown commented 7 years ago

Hi there,

I'm using Webpack to do some pretty intense transformation and was trying to get Jest working with it to make life easier. I stumbled across your package and gave it a try, however I keep getting this when I run yarn test:

$ yarn test
yarn test v0.27.5
$ jest-webpack

<project directory>/node_modules/jest-config/build/findConfig.js:27
  const isJS = directory.endsWith('.js');
                        ^
TypeError: Cannot read property 'endsWith' of undefined
    at findConfig (<project directory>/node_modules/jest-config/build/findConfig.js:27:25)
    at readOptions (<project directory>/node_modules/jest-config/build/index.js:53:10)
    at readConfig (<project directory>/node_modules/jest-config/build/index.js:27:22)
    at main (<project directory>/node_modules/@mzgoddard/jest-webpack/src/jest-webpack.js:34:22)
    at run (<project directory>/node_modules/@mzgoddard/jest-webpack/jest-webpack.js:38:3)
    at Object.<anonymous> (<project directory>/node_modules/@mzgoddard/jest-webpack/jest-webpack.js:42:3)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3
error Command failed with exit code 1.

In my case we're using Typescript, so our files actually end with .ts or .tsx most of the time. Is there any way I can help debug the issue?

mzgoddard commented 7 years ago

@blargity What version of webpack are you using? Is it webpack 1? My first thought is you don't have the webpack context option set in your config. jest-webpack is currently using that option as a placeholder and passing it as the root dir (which would otherwise in jest by default be process.cwd()). If you set that it should get past that error.

Outside that possibility, can you list your webpack and jest version?

atomicpages commented 7 years ago

@blargity setting context did the trick for me.

joacim-boive commented 7 years ago

I have the same problem, but I do have context set. context: '/Users/jboive/intellij/awesome-weather/src',

Using the latest and greatest of everything (as of this writing). Any input would be greately appreciated!

My webpack.config.babel.js file:

/* eslint no-console:"off" */
const webpack = require('webpack');

const HtmlWebpackPlugin = require('html-webpack-plugin');
// const InlineManifestWebpackPlugin = require('inline-manifest-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const PurifyCSSPlugin = require('purifycss-webpack');

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const DashboardPlugin = require('webpack-dashboard/plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');

const {resolve} = require('path');
const {getIfUtils, removeEmpty} = require('webpack-config-utils');
const glob = require('glob');

const PATHS = {
    src: resolve('src'),
    dist: resolve('dist'),
};

// const OfflinePlugin = require('offline-plugin/runtime').install();

module.exports = (env) => {
    const {ifProd, ifNotProd} = getIfUtils(env);
    const config = {
        context: resolve('src'),
        entry: './js/index/index.js',
        output: {
            filename: 'bundle.[name].[hash].js',
            path: resolve('dist'),
            pathinfo: ifNotProd()
        },
        // devtool: 'source-map', For CSS source-maps to work
        // devtool: 'eval-source-map' for JS source-maps to work - this is triggered for dev-server.
        devtool: ifNotProd('eval-source-map', 'source-map'),
        module: {
            rules: [
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /(node_modules)/
                },
                {
                    test: /\.js$/,
                    loader: 'eslint-loader',
                    exclude: /(node_modules)/
                },
                {
                    test: /\.css$/,
                    use: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: [
                            {
                                loader: 'css-loader',
                                options: {importLoaders: 1, minimize: true, sourceMap: true}
                            }
                        ]
                    })
                },
                {
                    test: /\.html$/,
                    use: {
                        loader: 'html-loader'
                    }
                },
                {
                    test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: 'url-loader?limit=10000&mimetype=application/font-woff',
                    query: {
                        name: 'static/media/files/[name].[hash:8].[ext]'
                    }
                }, {
                    test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: 'file-loader',
                    query: {
                        name: 'static/media/fonts/[name].[hash:8].[ext]'
                    }
                },
                {
                    test: /\.(gif|jpe?g|png)$/,
                    loader: 'url-loader?limit=25000',
                    query: {
                        limit: 10000,
                        name: 'static/media/images/[name].[hash:8].[ext]'
                    }
                }
            ]
        },
        plugins: removeEmpty([
            // ifProd(new InlineManifestWebpackPlugin()),
            // ifProd(new webpack.optimize.CommonsChunkPlugin({
            //     names: ['manifest']
            // })),
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: ifProd('"production"', '"development"')
                }
            }),
            new ProgressBarPlugin(),
            new HtmlWebpackPlugin({
                template: './index.html'
                // inject: 'head'
            }),
            // new OfflinePlugin(),
            new UglifyJSPlugin({
                    parallel: {
                        cache: true
                    },
                    sourceMap: true
                }
            ),
            new OptimizeCssAssetsPlugin({
                cssProcessorOptions: {
                    preset: 'default',
                    map: {inline: false}
                }
            }),
            new ExtractTextPlugin('styles.[name].[hash].css'),
            ifProd(new PurifyCSSPlugin({
                // Give paths to parse for rules. These should be absolute!
                paths: glob.sync(`${PATHS.src}/**/*.html`, {nodir: true}),
                verbose: true
            })),
            ifProd(new BundleAnalyzerPlugin()),
            ifNotProd(new webpack.NamedModulesPlugin()),
            new DashboardPlugin()
        ])
    };
    if (env.debug) {
        debugger // eslint-disable-line
    }

    console.log(config);

    return config;
};
joacim-boive commented 7 years ago

The problem, or one of them at least, is that my setup returns a function and not an object - like jest-webpack expects.

My webpack skills is... Improving. :) So, maybe there's a better solution but one way I could continue with my setup was to make a slight change in src/jest-webpack.js to account for my setup:

function main(argv, thisConfig) {
  // Ensure JestWebpackPlugin is active

  // Echo jest's argv and jest config behaviour
  const jestArgv = yargs(argv)
    .options(jestArgs.options)
    .check(jestArgs.check).argv;
  const config = typeof(thisConfig) === 'function' ? thisConfig({}) : thisConfig; 
  const jestConfig = readConfig(jestArgv, config.context);

But then it fails on TypeError: Cannot read property 'compiler' of null shared-data.js const shortResource = relative(this.compilation.compiler.options.context, resource);

positonic commented 5 years ago

setting 'publicPath' fixed this for me