Today, I had a very unusual problem. An Ionic v3 app that we are developing worked fine in development, but when compiled in production mode (ionic build --prod
) would fail to launch. When connected to a web inspector, the error thrown was
Error: Cannot use e "__Schema" from another module or realm.
Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.
https://yarnpkg.com/en/docs/selective-version-resolutions
Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.
The GraphQL library is throwing a fatal error as it believes there are multiple versions loaded. We aren't using GraphQL, but we are using AWS Amplify which includes GraphQL as part of its API module.
This error has been reported in both the AWS-Amplify aws-amplify/issue#2275 aws-amplify/issue#1445 (and others) GraphQL repos graphql-js/issues#1182
In our case, the error is caused by uglification of the app that causes GraphQL to mistakenly believe there are multiple versions installed. It is possible to disable this check in production mode by setting NODE_NEV=production. However as Ionic is built using Webpack, setting NODE_ENV=production isn't as simple as setting the env variable when building the app.
The solution in our case is to create a custom webpack.config.js for our project. And use this custom config to inject NODE_ENV=production into the built app.
To do this, here are the steps.
const merge = require("webpack-merge");
const common = require("@ionic/app-scripts/config/webpack.config.js");
const webpack = require("webpack");
module.exports = {
dev: common.dev,
prod: merge(common.prod, {
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": "production"
})
]
})
};
There are a couple of things happening here.
- I get the default ionic webpack config from the
@ionic/app-scripts
node module - I am using webpack-merge library to help merge our custom config with the default
- Ionic expects webpack.config.js to export 1 object with valid webpack configs for each environment. In this case, we export an object with the default dev environment, and export an updated prod config, that takes the ionic default config and updates it with a new plugin.
- I am using the Webpack Define Plugin to define process.env.NODE_ENV in the resulting bundle. Setting this to
'production'
disables the GraphQL check that throws the error.
{
...,
"config": {
"ionic_webpack": "./config/webpack.config.js"
}
}
Adding config.ionic_webpack
to package.json
tells the ionic build system to use the custom webpack.config.js
when building the app.
And after all that, our production build works again.
Please note that this only applies to ionic v3 apps. I haven't experienced this problem with our Ionic v4 apps.
Thank you so much I had been searching for solutions for two days and yours work for me. Just one thing, it throwed 'production not defined' and I found a fix here: thgh/vuejs-templates-rollup#1 (comment) change
'production'
to'"production"'
:Actually I solved it in my case by changing webpack config from:
to:
Originally posted by @anthonygore in thgh/vuejs-templates-rollup#1 (comment)