Open halvardssm opened 2 years ago
I am having the same issue. parts of a dependency are being "stripped away" during build and do not exist in the bundle. they do, however, exist in the source maps. so local development works fine. but when using just the bundle (via the build output), pieces are completely missing.
seems to be a possible duplicate of #7580 and #7555
using redux-toolkit query in a react 17 app, one of the functions available as an export from @reduxjs/toolkit/query/react
, fetchBaseQuery
, can not be found in the build, with the following error being thrown in the browser:
Uncaught TypeError: Gh.fetchBaseQuery is not a function
strangely, when looking through the build's bundles, the definition for that function can be found in the source maps. however, in the bundled javascript file, the only reference to fetchBaseQuery can be found in the line causing the above error to be thrown. I can see when Gh is defined and built out, but fetchBaseQuery is not a part of it. furthermore, (referencing the following screenshots) it appears as if fetchBaseQuery should be found on qh instead of Gh , based on the bundle. |
description | screenshot |
---|---|---|
bundled source code line causing the error to be thrown | ||
bundled source code showing where Gh is defined |
||
source mapped output showing the original code (where error is being thrown) |
babel.config.json (only used for jest tests)
{
"env": {
"test": {
"presets": [
"@parcel/babel-preset-env",
"@babel/preset-typescript",
"@babel/preset-react"
]
}
}
}
.parcelrc.json
{
"extends": "@parcel/config-default",
"transformers": {
"*.{js,mjs,jsm,jsx,es6,cjs,ts,tsx}": [
"@parcel/transformer-babel",
"@parcel/transformer-js",
"@parcel/transformer-react-refresh-wrap"
]
}
}
build script:
"build": "parcel build src/index.html --public-url /app --no-source-maps",
package.json (everything is up to date):
{
...
"dependencies": {
"@auth0/auth0-react": "^1.9.0",
"@optimizely/react-sdk": "^2.8.0",
"@ramsey-design-system/button": "^2.0.1",
"@ramsey-design-system/icon": "^2.0.0",
"@ramsey-design-system/icons": "^2.3.1",
"@ramsey-design-system/link": "^1.3.1",
"@reduxjs/toolkit": "^1.7.1",
"apophenia-javascript-logger": "^2.0.3",
"gazelle-design-system": "^1.16.3",
"postcss-modules": "^4.3.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^6.2.0",
"redux": "^4.1.2",
"styled-components": "^5.3.3",
"typescript": "^4.5.5"
},
"scripts": {
"clean": "rm dist/* .parcel-cache/* || true",
"build": "parcel build src/index.html --public-url /app --no-source-maps",
"start": "parcel src/index.html --open --port 3000",
"start-fresh": "yarn clean && yarn build && yarn start",
"test": "jest",
"test:watch": "jest --watch"
},
"devDependencies": {
"@babel/core": "^7.16.12",
"@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"@googlemaps/jest-mocks": "^2.3.0",
"@parcel/babel-preset-env": "^2.2.1",
"@parcel/transformer-sass": "^2.2.1",
"@ramseyinhouse/eslint-config": "^1.0.4",
"@ramseyinhouse/stylelint-config": "^1.1.0",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"@types/google.maps": "^3.47.3",
"@types/jest": "^27.4.0",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/react-router-dom": "^5.3.3",
"@types/styled-components": "^5.1.21",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"autoprefixer": "^10.4.2",
"axios": "^0.25.0",
"babel-jest": "^27.4.6",
"babel-plugin-styled-components": "^2.0.2",
"eslint": "^8.8.0",
"eslint-plugin-react-hooks": "^4.3.0",
"jest": "^27.4.7",
"jest-styled-components": "^7.0.8",
"modules": "^0.4.0",
"msw": "^0.36.8",
"parcel": "^2.2.1",
"plugins": "^0.4.2",
"postcss": "^8.0.0",
"postcss-custom-properties": "^12.1.4",
"postcss-import": "^14.0.2",
"postcss-url": "^10.1.3",
"prettier": "^2.5.0",
"redux-devtools": "^3.7.0",
"stylelint": "^14.3.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-sass-guidelines": "^9.0.1",
"stylelint-config-standard-scss": "^3.0.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-order": "^5.0.0",
"stylelint-processor-styled-components": "^1.10.0",
"typescript-plugin-styled-components": "^2.0.0"
},
...
}
fetchBaseQuery
definition should be found and no error should be thrown. the definition of fetchBaseQuery
should be included in the bundle
fetchBaseQuery
definition can not be found.
note in the source maps, fetchBaseQuery
can be found, thus it works fine in local development. however, in the bundled js file, the definition for fetchBaseQuery
can not be found.
n/a. sorry 😕
this one is frustratingly misleading. the old "works on my machine"! the 'missing' function is defined properly in the source maps, thus local development sees no issue. however when deployed to a production environment via parcel build ... --no-source-maps
the whole application tanks because of that uncaught error
this is probably not helpful, but here is how the missing function is being used:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
const API_BASE_URL = 'https://somewebsite.com/api';
const searchApi = createApi({
reducerPath: 'searchApi',
baseQuery: fetchBaseQuery({ baseUrl: API_BASE_URL }),
endpoints: (builder) => ({
getProsByProgramAndZip: builder.query({
query: ({ program, zip }) =>
`/pro/search?programKey=${program}&postalCodes=${zip}`,
}),
}),
});
const { useGetProsByProgramAndZipQuery } = searchApi;
export { API_BASE_URL, searchApi, useGetProsByProgramAndZipQuery };
Software | Version(s) |
---|---|
Parcel | 2.2.1 |
Node | 14.18.1 |
Yarn | 1.22.17 |
Operating System | macOS Monterey 12.1 |
did some more digging on this. looks like in my case above the issue is that parcel (or, parcel-bundler?) is not recognizing aliased files.
@reduxjs/toolkit/query/react
is just doing export * from '@reduxjs/toolkit/query'
, so for some reason parcel is not recognizing those exports.
When I change this line:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
to this:
import { createApi } from '@reduxjs/toolkit/query/react';
import { fetchBaseQuery } from '@reduxjs/toolkit/query';
which is nothing more than explicit imports rather than using aliased (is that the right term?) imports, the bundler correctly grabs the definition of fetchBaseQuery
.
the super strange thing is that the correct definition of fetchBaseQuery
can be found in the source maps, but not in the minified bundle. so, in local development it works fine (using source maps) but deployed it does not (using only the bundle).
I don't know where to go from this, but I feel like this is some pretty good context to diagnose exactly what's failing in the bundler!
Reproduction for that RTK problem:
// index.js
import { createApi, fetchBaseQuery } from "./lib";
console.log(createApi, fetchBaseQuery);
// lib/package.json
{"sideEffects": false}
// lib/index.js
console.log(this);
export * from "./lib1.js";
export var createApi = 123;
// lib/lib1.js
export function fetchBaseQuery(){}
I'm trying to figure out whether our issue is the same as this. I think so?
import * as GraphApi from "./graph"
export { GraphApi }
publish this as mynpm
import { GraphApi } from 'mynpm'
Module '"mynpm"' has no exported member 'GraphApi'.
I'm actually not sure how to work around this issue. One can hack it for non-types (such as re-exporting functions), but typescript does not allow exporting types as part of a const
. And, when I try
export * as GraphApi from './graph'
I get, from parcel
@parcel/transformer-typescript-types: node.exportClause.elements is not iterable
We reproduce it with https://gitlab.com/giro3d/giro3d-sample-application. Our workaround is to use --no-optimize
I'm running into a similar issue on Parcel 2.9.3, where I have a module in my application which exports a single object (and depends on no other modules).
export const routes = {
home: () => '/',
search: () => '/search',
account: () => '/account',
login: () => '/login',
forgotPassword: () => '/forgot-password',
notFound: () => '/not-found',
};
If I run parcel with optimization enabled this module gets "optimized out". Other places that reference this module then end up with this routes
just being an empty object, so they fail trying to call routes.home()
since routes.home
is undefined.
Interestingly if I do something else to reference this object, like console.log(routes)
within this module, then it behaves properly.
Similarly if I run with --no-optimize
the problem goes away, but that is not ideal. Please let me know if I can provide any more information!
Edit: Trying to add more context if it's helpful. Things that do "fix" this problem
console.log(routes)
in that same moduleJSON.stringify(routes)
in that moduleThings that do not
routes.home = () => '/';
)This was not always the case. I set this project up a couple of months ago with no issue. I recently cleared out my node_modules and package-lock, and reinstalled all dependencies. I now see this issue. I'm still trying to understand what dependency changed to uncover this, as I have a huge diff in my package-lock. Will update this comment as I find anything
🐛 bug report
Hi! I am trying to refactor an npm package from js/jquery to ts, and in the update process, I wanted to use Parcel as bundler due to its ease of use and zero config. When using
parcel build
, the code gets generated, but functions and enums are not accessible in the bundle nor exported.🎛 Configuration (.babelrc, package.json, cli command)
package.json
tsconfig.json
🤔 Expected Behavior
Enums and functions should be exported from and be accessible in the bundle
😯 Current Behavior
💁 Possible Solution
🔦 Context
💻 Code Sample
https://github.com/halvardssm/clippy.js
To reproduce:
parcel-repro
yarn install
yarn pack
"clippy": "file:./clippy.js-v2.0.0.tgz",
to depsyarn install
yarn start
and visit the page in the browserTo verify that the issues are only happening when bundling with parcel, checkout branch
refactor
and start the app.🌍 Your Environment