在 webpack react 应用程序中创建一个测试入口点
create a test entry point in webpack react application
tldr:我能够 require
制作应用程序的所有内容 运行,但是如果我 require
来自测试(在应用程序中 - 请参阅下面的目录结构)文件,整个依赖链中断。
我在require
-ing 从我的 app/test
目录(在我的 webpack React.js 应用程序中)的组件中遇到一些困难 require
-从 /app
文件夹中的任何其他文件下载。这是目录结构
app
/components/checkout.jsx
/components/button.jsx
/test/test.js
index.jsx
dist
node_modules
webpack.config.js
package.json
在我的 webpack.config.js 中,我将它设置为像这样为我的 React 应用程序使用 jsx-loader
entry: {
app: "./app/index"
},
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony',
}
]
},
resolve: {
extensions: ['', '.js', '.jsx']
}
这允许我要求以扩展名 .jsx 结尾的文件。例如,在 /app/index.jsx
中,我需要 /app/components/checkout.jsx
通过
var Checkout = require('./components/Checkout')
在 /app/components/checkout.jsx
里面,我需要按钮
var Button = require('./components/Button')
所以当我从 index.jsx 请求 Checkout
时,它可以毫无问题地处理按钮的请求。
然而,从app/test/test.js,我
var Checkout = require('../components/Checkout')
webpack 找不到 Checkout 组件。当我在 webpack 开发服务器中查看测试时,它没有显示已查找 .jsx 文件扩展名。它搜索
app/components/Checkout
app/components/Checkout.webpack.js
app/components/Checkout.web.js
app/components/Checkout.js
app/components/Checkout.json
因此,我尝试像这样使用 jsx-loader
内联
var Checkout = require(jsx-loader!'../components/Checkout')
从测试目录,webpack 现在可以找到该文件,但它会抛出一个错误,指出它无法解析 Checkout requires
的按钮。换句话说,当我使用 app/test
文件夹中的 require
时,整个依赖链不同步。
如何更改我的 webpack.config.js 以便能够在具有此目录结构的测试中需要应用程序文件,或者更一般地说,如何配置 webpack 以在测试中需要应用程序文件?
更新
项目结构
/app
/test/test.js
/index.jsx
/components/checkout.jsx (and button.jsx)
/dist
/node_modules
package.json
webpack.config.js
整个 webpack 配置
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')
]
}
一个可能的解决方案是始终要求文件扩展名:
var Checkout = require('./components/Checkout.jsx')
我猜可能是因为将 "test" 设置为根目录。但直到你分享你的代码才清楚。你能给我一个 link 到 GitHub 的回购或什么的吗?
我看到你在使用和声参数,我可以假设你在使用 es6 吗?
如果是这样的话,我之前遇到过这个问题,对我来说问题是文件被添加到 es5 中,作为 es6 没有经过蜜蜂转换,由 jsx-loader / babel-loader 添加到 es5。
所以我需要补充:
preLoaders: [{
test: [/\.jsx$/, /\.js$/],
include: // modules here
loaders: ['babel-loader?optional[]=runtime']
}]
但这并不能解释为什么这只对您的测试失败。也许你可以详细说明当你 运行 你的测试时 运行ned 是什么
但现在我仍然假设你使用 es6,
如果你不是上述情况,尝试安装本地版本的webpack,并在你的本地目录和你的应用程序文件夹中寻找它
(resolveLoader: { root: path.join(__dirname, "node_modules") })
希望这个帮助ps
编辑:ps 查看你的配置,resolveLoader 不应该是你的 resolve 的一部分,在我使用的另一个 webpack 设置中,我有以下设置
用于解决:
resolve: {
extensions: ['', '.js', '.jsx', '.json'],
modulesDirectories: ['node_modules', 'node_modules/vl_tooling/node_modules']
},
resolveLoader: {
modulesDirectories: ['node_modules', 'node_modules/vl_tooling/node_modules']
},
我为 运行 React 测试设置了单独的 gulp 任务,也许你可以重用这个想法:
karma.js
var karma = require('gulp-karma'),
_ = require('lodash'),
Promise = require('bluebird'),
plumber = require('gulp-plumber'),
path = require('path'),
webpack = require('gulp-webpack'),
named = require('vinyl-named');
module.exports = function (gulp, options) {
var root = path.join(options.cwd, 'app'),
extensions = ['', '.js', '.jsx'],
modulesDirectories = ['node_modules'];
gulp.task('karma', ['karma:build'], function () {
return runAllTests(gulp, options);
});
gulp.task('karma:build', function() {
var optionsForTests = _.merge({
ignore: ['**/node_modules/**']
}, options);
return gulp.src(['**/__tests__/*.js'], optionsForTests).
pipe(named(function(file){
// name file bundle.js
return 'bundle';
})).
pipe(webpack({
module: {
loaders: [
// runtime option adds Object.assign support
{ test: /\.(js|jsx)$/, loader: 'babel-loader?optional[]=runtime', exclude: /node_modules/},
{ test: /\.(sass|scss)$/, loader: 'css-loader!sass-loader'},
{ test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/, loader: 'url-loader'},
{ test: /\.(ttf|eot)$/, loader: 'file-loader'},
{ test: /sinon.*\.js$/, loader: 'imports?define=>false' } // hack due to https://github.com/webpack/webpack/issues/304
]
},
resolve: {
root: root,
extensions: extensions,
modulesDirectories: modulesDirectories
}
})).
pipe(gulp.dest('test-build'));
})
}
function runAllTests(gulp, options) {
var optionsForTests = _.merge({
ignore: ['**/node_modules/**']
}, options);
return new Promise(function (resolve, reject) {
var karmaConfig = path.join(path.resolve(__dirname, '..'), 'karma.conf.js');
// shim Prototype.function.bind in PhantomJS 1.x
var testFiles = [
'node_modules/es5-shim/es5-shim.min.js',
'node_modules/es5-shim/es5-sham.min.js',
'test-build/bundle.js'];
gulp.src(testFiles).
pipe(plumber({
errorHandler: function (error) {
console.log(error);
this.emit('end');
}
})).
pipe(karma({
configFile: karmaConfig,
action: 'run'
})).
on('end', function () { resolve(); });
});
}
Gulp 文件:
var gulp = require('gulp');
var auctionataBuild = require('auctionata-build');
var path = require('path');
auctionataBuild.tasks.karma(gulp, {
cwd: path.resolve(__dirname)
});
运行 来自终端:
gulp karma
tldr:我能够 require
制作应用程序的所有内容 运行,但是如果我 require
来自测试(在应用程序中 - 请参阅下面的目录结构)文件,整个依赖链中断。
我在require
-ing 从我的 app/test
目录(在我的 webpack React.js 应用程序中)的组件中遇到一些困难 require
-从 /app
文件夹中的任何其他文件下载。这是目录结构
app
/components/checkout.jsx
/components/button.jsx
/test/test.js
index.jsx
dist
node_modules
webpack.config.js
package.json
在我的 webpack.config.js 中,我将它设置为像这样为我的 React 应用程序使用 jsx-loader
entry: {
app: "./app/index"
},
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony',
}
]
},
resolve: {
extensions: ['', '.js', '.jsx']
}
这允许我要求以扩展名 .jsx 结尾的文件。例如,在 /app/index.jsx
中,我需要 /app/components/checkout.jsx
通过
var Checkout = require('./components/Checkout')
在 /app/components/checkout.jsx
里面,我需要按钮
var Button = require('./components/Button')
所以当我从 index.jsx 请求 Checkout
时,它可以毫无问题地处理按钮的请求。
然而,从app/test/test.js,我
var Checkout = require('../components/Checkout')
webpack 找不到 Checkout 组件。当我在 webpack 开发服务器中查看测试时,它没有显示已查找 .jsx 文件扩展名。它搜索
app/components/Checkout
app/components/Checkout.webpack.js
app/components/Checkout.web.js
app/components/Checkout.js
app/components/Checkout.json
因此,我尝试像这样使用 jsx-loader
内联
var Checkout = require(jsx-loader!'../components/Checkout')
从测试目录,webpack 现在可以找到该文件,但它会抛出一个错误,指出它无法解析 Checkout requires
的按钮。换句话说,当我使用 app/test
文件夹中的 require
时,整个依赖链不同步。
如何更改我的 webpack.config.js 以便能够在具有此目录结构的测试中需要应用程序文件,或者更一般地说,如何配置 webpack 以在测试中需要应用程序文件?
更新
项目结构
/app
/test/test.js
/index.jsx
/components/checkout.jsx (and button.jsx)
/dist
/node_modules
package.json
webpack.config.js
整个 webpack 配置
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')
]
}
一个可能的解决方案是始终要求文件扩展名:
var Checkout = require('./components/Checkout.jsx')
我猜可能是因为将 "test" 设置为根目录。但直到你分享你的代码才清楚。你能给我一个 link 到 GitHub 的回购或什么的吗?
我看到你在使用和声参数,我可以假设你在使用 es6 吗?
如果是这样的话,我之前遇到过这个问题,对我来说问题是文件被添加到 es5 中,作为 es6 没有经过蜜蜂转换,由 jsx-loader / babel-loader 添加到 es5。
所以我需要补充:
preLoaders: [{
test: [/\.jsx$/, /\.js$/],
include: // modules here
loaders: ['babel-loader?optional[]=runtime']
}]
但这并不能解释为什么这只对您的测试失败。也许你可以详细说明当你 运行 你的测试时 运行ned 是什么 但现在我仍然假设你使用 es6,
如果你不是上述情况,尝试安装本地版本的webpack,并在你的本地目录和你的应用程序文件夹中寻找它
(resolveLoader: { root: path.join(__dirname, "node_modules") })
希望这个帮助ps
编辑:ps 查看你的配置,resolveLoader 不应该是你的 resolve 的一部分,在我使用的另一个 webpack 设置中,我有以下设置 用于解决:
resolve: {
extensions: ['', '.js', '.jsx', '.json'],
modulesDirectories: ['node_modules', 'node_modules/vl_tooling/node_modules']
},
resolveLoader: {
modulesDirectories: ['node_modules', 'node_modules/vl_tooling/node_modules']
},
我为 运行 React 测试设置了单独的 gulp 任务,也许你可以重用这个想法:
karma.js
var karma = require('gulp-karma'),
_ = require('lodash'),
Promise = require('bluebird'),
plumber = require('gulp-plumber'),
path = require('path'),
webpack = require('gulp-webpack'),
named = require('vinyl-named');
module.exports = function (gulp, options) {
var root = path.join(options.cwd, 'app'),
extensions = ['', '.js', '.jsx'],
modulesDirectories = ['node_modules'];
gulp.task('karma', ['karma:build'], function () {
return runAllTests(gulp, options);
});
gulp.task('karma:build', function() {
var optionsForTests = _.merge({
ignore: ['**/node_modules/**']
}, options);
return gulp.src(['**/__tests__/*.js'], optionsForTests).
pipe(named(function(file){
// name file bundle.js
return 'bundle';
})).
pipe(webpack({
module: {
loaders: [
// runtime option adds Object.assign support
{ test: /\.(js|jsx)$/, loader: 'babel-loader?optional[]=runtime', exclude: /node_modules/},
{ test: /\.(sass|scss)$/, loader: 'css-loader!sass-loader'},
{ test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/, loader: 'url-loader'},
{ test: /\.(ttf|eot)$/, loader: 'file-loader'},
{ test: /sinon.*\.js$/, loader: 'imports?define=>false' } // hack due to https://github.com/webpack/webpack/issues/304
]
},
resolve: {
root: root,
extensions: extensions,
modulesDirectories: modulesDirectories
}
})).
pipe(gulp.dest('test-build'));
})
}
function runAllTests(gulp, options) {
var optionsForTests = _.merge({
ignore: ['**/node_modules/**']
}, options);
return new Promise(function (resolve, reject) {
var karmaConfig = path.join(path.resolve(__dirname, '..'), 'karma.conf.js');
// shim Prototype.function.bind in PhantomJS 1.x
var testFiles = [
'node_modules/es5-shim/es5-shim.min.js',
'node_modules/es5-shim/es5-sham.min.js',
'test-build/bundle.js'];
gulp.src(testFiles).
pipe(plumber({
errorHandler: function (error) {
console.log(error);
this.emit('end');
}
})).
pipe(karma({
configFile: karmaConfig,
action: 'run'
})).
on('end', function () { resolve(); });
});
}
Gulp 文件:
var gulp = require('gulp');
var auctionataBuild = require('auctionata-build');
var path = require('path');
auctionataBuild.tasks.karma(gulp, {
cwd: path.resolve(__dirname)
});
运行 来自终端:
gulp karma