【问题标题】:Using webpack aliases in mocha tests在 mocha 测试中使用 webpack 别名
【发布时间】:2016-02-20 23:34:38
【问题描述】:

我正在使用 React/Redux/Webpack 开发一个 Web 应用程序,现在开始将测试与 Mocha 集成。

我关注了the instructions for writing tests in the Redux documentation,但现在我的 webpack 别名遇到了问题。

例如,看看我的一个动作创建者的这个测试的导入部分:

import expect       from 'expect'                 // resolves without an issue
import * as actions from 'actions/app';           // can't resolve this alias
import * as types   from 'constants/actionTypes'; // can't resolve this alias

describe('Actions', () => {
  describe('app',() => {
    it('should create an action with a successful connection', () => {

      const host = '***************',
            port = ****,
            db = '******',
            user = '*********',
            pass = '******';

      const action = actions.createConnection(host, port, db, user, pass);

      const expectedAction = {
        type: types.CREATE_CONNECTION,
        status: 'success',
        payload: { host, port, database, username }
      };

      expect(action).toEqual(expectedAction);
    });
  });
});

正如 cmets 所建议的,mocha 在引用别名依赖项时无法解析我的导入语句。

因为我还是 webpack 的新手,所以这里是我的webpack.config.js

module.exports = {
  devtool: 'eval-source-map',
  entry: [
    'webpack-hot-middleware/client',
    './src/index'
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  resolve: {
    extensions : ['', '.js', '.jsx'],
    alias: {
      actions: path.resolve(__dirname, 'src', 'actions'),
      constants: path.resolve(__dirname, 'src', 'constants'),
      /* more aliases */
    }
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],
  module: {
    loaders: [{
      test: /\.js$/,
      loaders: ['babel'],
      exclude: /node_modules/,
      include: __dirname
    }]
  }
};

另外,我正在使用命令 npm test 来运行 mocha,这是我在 package.json 中使用的脚本。

 {   
   "scripts": {
     "test": "mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
   }
 }

所以这就是我卡住的地方。 我需要在运行时将 webpack 的别名包含到 mocha 中。

【问题讨论】:

  • 我也遇到了同样的问题,你找到解决办法了吗?
  • 是的,刚刚发布了我的答案。 YMMV

标签: reactjs npm mocha.js webpack redux


【解决方案1】:

好的,所以我意识到我的别名都在 src/ 目录中,所以我只需要修改我的 npm run test 脚本。

{   
  "scripts": {
    "test": "NODE_PATH=./src mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
  }
}

可能不适用于所有人,但这解决了我的问题。

【讨论】:

  • 谢谢,我试试这个。
  • 我所有的东西也在src 中,但不确定如何对我的测试脚本实施修复:find ./src -name '*.test.js' | xargs mocha --require babel-core/register
  • 这是一个最优秀的解决方案,尤其是与 mocking 和 proxying require 相比!!
  • 这对我来说非常适合单次测试运行,但我无法成功观看别名目录中的文件,您观看成功了吗?
  • 我已经开始使用mocha-webpack 而不是这种解决方法。 github.com/zinserjan/mocha-webpack
【解决方案2】:

您还可以使用我编写的 babel 插件: https://github.com/trayio/babel-plugin-webpack-alias 只需将 babel 插件添加到您的 .babelrc,它就会将您的别名路径转换为相对路径。

【讨论】:

  • 我点击了你的链接,根据那里的用户信息和这里的用户信息判断,看起来你是插件的作者,所以我进行了相应的编辑,因为它违反了 SO 规则提及您在答案中创建的软件没有明确表明您创作了它。 (这样做会被视为垃圾邮件,并会受到严厉处罚。)如果您不是作者,您可以回滚我的编辑,但请务必澄清,否则,下一个点击链接的人可能会做出与我相同的推断。
  • 此外,这个答案目前只是边界链接。添加有关如何安装和使用插件的信息将解决此问题。
  • 我没有在生产中使用它,但我现在正在使用它进行开发。它似乎完全符合预期。我是别名的粉丝,我认为使用 babel-plugin 来解决这个问题是要走的路。我没有查看源代码或其他任何内容,但到目前为止工作正常。
【解决方案3】:

我也遇到了同样的问题,但是用这个插件我解决了。

https://www.npmjs.com/package/babel-plugin-webpack-aliases

你的“mocha”执行命令没有读取webpack.config.js,所以无法解析别名。
通过设置这个插件,在使用“babel-core/register”编译时考虑webpack.config.js。因此,别名在测试期间也将有效。

npm i -D babel-plugin-webpack-aliases

并将此设置添加到.babelrc

{
    "plugins": [
        [ "babel-plugin-webpack-aliases", { "config": "./webpack.config.js" } ] 
    ]
}

【讨论】:

    【解决方案4】:

    丹尼的回答很棒。但我的情况有点不同。 我使用webpack的resolve.alias来使用src文件夹下的所有文件。

    resolve: {
      alias: {
        '-': path.resolve(__dirname, '../src'),
      },
    },
    

    并为我自己的模块使用特殊前缀,如下所示:

    import App from '-/components/App';
    

    像这样测试代码 我必须在 mocha 测试之前添加一个命令 ln -sf src test/alias/- 并使用 NODE_PATH=./test/alias 技巧丹尼阵营。所以最终的脚本会是这样的:

    {   
      "scripts": {
        "test": "ln -sf src test/alias/-; NODE_PATH=./test/alias mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
      }
    }
    

    PS:

    我使用了-,因为像@~ 这样的美丽字符不够安全。我找到了安全字符的答案here

    【讨论】:

      【解决方案5】:

      我想我解决了这个问题。您应该使用 2 个包:mock-requireproxyquire

      假设你有一个这样的 js 文件:

      app.js

      import action1 from 'actions/youractions';   
      
      export function foo() { console.log(action1()) }; 
      

      你的测试代码应该这样写:

      app.test.js

      import proxyquire from 'proxyquire';
      import mockrequire from 'mock-require';
      
      before(() => {
        // mock the alias path, point to the actual path
        mockrequire('actions/youractions', 'your/actual/action/path/from/your/test/file');
        // or mock with a function
        mockrequire('actions/youractions', {actionMethod: () => {...}));
      
      let app;
      beforeEach(() => {
        app = proxyquire('./app', {});
      });
      
      //test code
      describe('xxx', () => {
        it('xxxx', () => {
          ...
        });
      });
      

      文件树

      app.js
        |- test
          |- app.test.js
      

      首先在 before 函数中通过 mock-require 模拟别名路径,然后在 beforeEach 函数中通过 proxyquire 模拟你的测试对象。

      【讨论】:

        【解决方案6】:

        我假设您的mocha.opts 中有--require babel-register。你可以使用 babel 模块解析器插件https://github.com/tleunen/babel-plugin-module-resolver。这允许你在 .babelrc 中设置别名,类似于你的 webpack 别名:

        {
          "plugins": [
            ["module-resolver", {
               "alias": {
                 "actions": "./src/actions",
                 "constants": "./src/constants"
               }
            }]
          ]
        }
        

        【讨论】:

          【解决方案7】:

          我遇到了完全相同的问题。在 require.js 或 node 的 require 中使用 webpack 别名似乎是不可能的。

          我最终在单元测试中使用了mock-require,只是手动替换了路径,如下所示:

          var mock = require('mock-require');
          
          mock('actions/app', '../../src/actions/app');
          

          mock-require 是一个很好的工具,因为您很可能希望模拟大部分依赖项,而不是使用来自src 的实际脚本。

          【讨论】:

          • 我使用mock-require时似乎没有工作,错误仍然说找不到模块'actions/xxx'。
          【解决方案8】:

          将别名保存在一个位置,例如config/webpack.common.js

          resolve: {
              alias: {
                  '~': path.resolve(__dirname, './../src/app')
              }
          }
          

          然后安装babel-plugin-webpack-alias

          npm i babel-plugin-webpack-alias --save-dev
          

          然后在.babelrc 中输入:

          {
              "presets": ["env"],
              "plugins": [
                  ["babel-plugin-webpack-alias", {
                      "config": "./config/webpack.common.js" // path to your webpack config
                  }]
              ]
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-03-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-07-26
            相关资源
            最近更新 更多