如何在Webpack构建中避免绑定模拟模块?

7
我们正在努力使我们的React + GraphQL项目独立于生态系统中的任何其他层,以提高开发人员的体验。为此,我们编写了一个薄的HOC,它包装了Apollo自己的graphql HOC,并使用内部环境变量在网络获取和模拟数据之间进行切换。在生产构建中,所有这些模拟数据显然都不会被使用,即使它们被import
有没有一种方法可以避免在Webpack的生产捆绑包中包含你知道不会需要的模块,同时保持其他所有内容相同/不破坏应用程序?
类似dynamic import()这样的东西可能起作用,但最终会将你的构建分块,而不是省略你不需要/不想要的内容。 更新:该应用程序是使用create-react-app 1.0.17创建的,后来被释放。

1
在生产环境中,将模拟数据模块解析为空模块是否可行?https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/webpack.config.prod.js - HMR
@DayanMorenoLeon 我理解你的想法。这与下面某个答案类似。但在这种情况下,恐怕不能简单地用另一个模块代替一个模块。 - Nicolás Fantone
在你的本地环境中,你替换了你的 Apollo 客户端,但是在生产环境中却没有。 - Dayan Moreno Leon
@NicolásFantone 可以在生产配置中为模拟数据模块添加别名: https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/webpack.config.prod.js#L100 我假设该模块不导出任何内容,但修改Apollo? 因此,当未加载该代码时,它不会改变任何内容。 - HMR
1
@whitep4nther 想把赏金给mauron85,但设置别名似乎是更干净的解决方案(一个全局开关而不是可能有许多文件具有条件导入语句)。我明天会检查一下是否有人添加了答案。 - HMR
显示剩余4条评论
2个回答

7
我正在使用以下目录结构。
api
  index.js
  apimock.js
  apirest.js

在index.js中,您根据NODE_ENV的不同切换实现方式:
if (process.env.NODE_ENV === 'production') {
  module.exports = require('./apirest');
} else {
  module.exports = require('./apimock');
}

您需要使用webpack DefinePlugin来设置NODE_ENV:

new webpack.DefinePlugin({
  'process.env': {
    NODE_ENV: `"${process.env.NODE_ENV || 'development'}"`,
    ENABLE_DEVTOOLS: JSON.stringify(!!process.env.ENABLE_DEVTOOLS)
  }
})

构建命令(npm脚本):
NODE_ENV=production webpack --config webpack.config.js

或者进行模拟实现:
NODE_ENV=development webpack --config webpack.config.js

Webpack只会根据NODE_ENV打包单个实现。

在您的组件(saga…)中,您只需导入api即可:

import * as api from 'api';

这个方法是可行的。但不幸的是,在我们的情况下并不那么简单,因为数据层是通过Apollo的graphql HOC进行访问的。不过,你给了我一些值得思考的东西。 - Nicolás Fantone

0
在你的 webpack.config.dev.js 文件中:
resolve: {
  alias:{
    "react-apollo":"./mock.js"
  }
}

现在所有请求 react-apollo 的模块在进行开发编译时都会得到模拟。

我没有 apollo-client,但这里有一个模拟 jQuery 的示例:

你的代码:

import $ from 'jquery';
console.log($().message)

webpack.dev.config.js:

alias:{
  "jquery":"./mock.js"
}

mock.js:

const org = require('../node_modules/jquery/src/jquery');
org.fn.message = "Hello from mock";
export default org;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接