rollup-plugin-babel not recognizing JSX - javascript

I am having issues with RollupJS API. For some reason, its not recognizing JSX syntax. Rollup (API) is giving me this error.
Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
2: import App from "./App";
3: const MyApp = (props) => {
4: return <View index={<App />} url={props.url} serverOptions={props.serverOptions}/>;
^
5: };
6: export default MyApp;
Here's the Rollup config.
export const loadBuildConfigurationOptions = (tsconfigOptions: object, root: Path = Process.Cwd()): RollupOptions => {
return <RollupOptions> {
input: Path.FromSegments(root, "src", "index.ts").toString(),
output: [
{
dir: Path.FromSegments(root, "dist").toString(),
format: "cjs"
}
],
external: [
"solid-js",
"solid-js/web",
"solidus"
],
plugins: [
typescript(tsconfigOptions),
nodeResolve({
preferBuiltins: true,
exportConditions: ["solid"],
extensions: [".js", ".jsx", ".ts", ".tsx"]
}),
nodePolyfill(),
babel({
babelHelpers: "bundled",
presets: [["solid", { generate: "ssr", hydratable: true }]],
}),
json(),
styles(),
copy({
targets: [
{ src: 'src/assets/**/*', dest: 'dist/src/assets' }
]
}),
],
preserveEntrySignatures: false,
treeshake: true,
};
}
I am using this in a build tool for a SolidJS SSR library I am developing. what is happening here is this function generates the appropriate Rollup configuration file to for the project being build by the user of this library. The returned Rollup configuration object is then being used by the Rollup JS API to build the actual application. Do I need to change the parameters in the babel plugin or something?

Okay. I figured it out. It’s quite silly really. I just had to make one change to the Babel plugin.
babel({
babelHelpers: "bundled",
presets: [["solid", { generate: "ssr", hydratable: true }]],
extensions: [“.js”, “.ts”, “.jsx”, “.tsx”],
}),
Adding the extensions option seemed to have fixed everything.

Related

Rollup library importing file with named and default export not working

I have a rollup library that is trying to use Antd react components. Without external component libraries, everything works fine. If I add the component library (material ui complains of a similar issue), it complains about trying to import variables that are not exported while importing the component library.
rollup.config.js:
export default [
{
input: 'src/index.ts',
output: [
{
file: packageJson.main,
format: 'cjs',
sourcemap: true,
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
plugins: [visualizer({ open: useVisualizer })],
},
{
file: packageJson.module,
format: 'esm',
sourcemap: true,
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
],
external: ['react', 'react-dom'],
plugins: [
resolve({
preferBuiltins: true
}),
commonjs({
transformMixedEsModules: true,
requireReturnsDefault: 'auto',
esmExternals: true,
// dynamicRequireTargets: ['node_modules/antd/es/**/*.js']
}),
typescript({ tsconfig: './tsconfig.json' }),
folder(),
postcss({
plugins: [],
}),
eslint(),
terser(),
],
},
{
input: './src/index.ts',
output: [{ file: 'dist/index.d.ts', format: 'esm' }],
plugins: [dts()],
external: [/\.css$/],
},
];
Error message:
[!] Error: 'Group' is not exported by node_modules/antd/es/radio/radio.js, imported by node_modules/antd/es/calendar/Header.js
However, when we look at the exports from radio.js, 'Group' is clearly exported from radio/index.js from within the radio directory:
import Group from './group';
import InternalRadio from './radio';
import Button from './radioButton';
export { Button, Group };
var Radio = InternalRadio;
Radio.Button = Button;
Radio.Group = Group;
Radio.__ANT_RADIO = true;
export default Radio;
Header.js imports this like so: import { Button, Group } from '../radio';, so the import SHOULD be going to radio/index.js, however, it appears it is actually going to radio/radio.js instead. No amount of rollup configuration has made this change so far. Any ideas how to get this to resolve to index.js instead of radio.js?
Turns out the normal node-resolve plugin does not resolve "local" imports (i.e. file system paths instead of package paths). The solution here is to also use rollup-plugin-local-resolve, which does resolve these paths.

Babel module resolver not working with react-native

My babel module resolver is not working with React-Native (neither does intellij in VScode)
Here, Is my babel config
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['./'],
alias: {
'#assets': './src/assets',
'#modules': './src/modules',
'#config': './src/config',
'#utils': './src/utils',
},
},
],
],
};
And jsconfig.json
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#assets": ["./assets"],
"#modules": ["./modules"],
"#config": ["./config"],
"#utils": ["./utils"]
}
}
}
I changed import for one of my files and this is the error I get when I executed the build command from Xcode
Error: Error loading assets JSON from Metro. Ensure you've followed
all expo-updates installation steps correctly. Unable to resolve
module ../../modules/store/components/Filters from
src/utils/Router.js:
None of these files exist:
Where I imported the file like this
import Filters from '#modules/store/components/Filters';
I had the same problem, I just removed the '#' from my aliases and it seems working fine now.
Here is my babel.config.js
module.exports = function (api) { ■ File is a CommonJS module; it may be converted to an ES6 module.
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: [
[
require.resolve("babel-plugin-module-resolver"),
{
root: ["./src/"],
alias: {
// define aliases to shorten the import paths
components: "./src/components",
containers: "./src/containers",
contexts: "./src/contexts",
interfaces: "./src/interfaces",
organizer: "./src/screens/organizer",
screens: "./src/screens",
},
extensions: [".js", ".jsx", ".tsx", ".ios.js", ".android.js"],
},
],
],
};
};
Try resetting the cache, if above suggested answers don't work
react-native start --reset-cache
This worked for me. For more info see here
Change your module-resolver's root to ['./src/']:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['./src/'], // <-- here ✅
alias: {
'#assets': './src/assets',
'#modules': './src/modules',
'#config': './src/config',
'#utils': './src/utils',
},
},
],
],
};

Rollup is not generating typescript sourcemap

I am using rollup with svelte + typescript + scss. My problem is that I am not able to generate source maps.
Following is my rollup config file:
import svelte from 'rollup-plugin-svelte'
import resolve from '#rollup/plugin-node-resolve'
import commonjs from '#rollup/plugin-commonjs'
import livereload from 'rollup-plugin-livereload'
import { terser } from 'rollup-plugin-terser'
import typescript from '#rollup/plugin-typescript'
import alias from '#rollup/plugin-alias'
const production = !process.env.ROLLUP_WATCH
const path = require('path').resolve(__dirname, 'src')
const svelteOptions = require('./svelte.config')
function serve() {
let server
function toExit() {
if (server) server.kill(0)
}
return {
writeBundle() {
if (server) return
server = require('child_process').spawn(
'yarn',
['run', 'start', '--', '--dev'],
{
stdio: ['ignore', 'inherit', 'inherit'],
shell: true,
}
)
process.on('SIGTERM', toExit)
process.on('exit', toExit)
},
}
}
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js',
},
plugins: [
alias({
entries: [
{ find: '#app', replacement: `${path}` },
{ find: '#components', replacement: `${path}/components` },
{ find: '#includes', replacement: `${path}/includes` },
{ find: '#styles', replacement: `${path}/styles` },
{ find: '#pages', replacement: `${path}/pages` },
],
}),
svelte(svelteOptions),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte'],
}),
commonjs(),
typescript({ sourceMap: !production }),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser(),
],
watch: {
clearScreen: false,
},
}
I am not sure what exactly am I doing wrong. Here is the link to code I am using.
Any help will be deeply appreciated!
This is what worked for me: you need to set sourceMap: false in the typescript rollup plugin options.
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
...
},
plugins: [
...
svelte(...),
typescript({ sourceMap: false }),
...
]
}
It turns out rollup's sourcemap collapser conflicts with the typescript's plugin sourcemap generator. That's why it works on prod builds but not in dev builds (because originally it is sourceMap: !production). Just let rollup do the heavy lifting.
As also mentioned by others, it seems like the combination of TypeScript and Rollup leads to the problem. Disabling the source map in TypeScript only fixes the problem of mapping Svelte to TypeScript. However you only receive a source map showing source in the compiled JavaScript, not in the original TypeScript. I finally found a solution, that worked for me: Just add the Option inlineSources: true to the TypeScript options:
typescript({ sourceMap: !production, inlineSources: !production }),
This circumvents the problem by simply not creating a duplicate SourceMap, but by copying the source code from TypeScript into the SourceMap.
For anyone using terser, not svelte, this solved the same problem for me:
import sourcemaps from 'rollup-plugin-sourcemaps';
import { terser } from 'rollup-plugin-terser';
import typescript from '#rollup/plugin-typescript';
export default [
{
input: 'dist/index.js',
output: [
{
file: 'dist/cjs/index.js',
format: 'cjs'
},
{
file: 'dist/fesm2015/index.js',
format: 'es'
}
],
plugins: [
sourcemaps(),
terser(),
typescript({ sourceMap: true, inlineSources: true })
]
}
];
Apparently rollup-plugin-sourcemaps is needed to do the magic necessary to utilize the map files generated by the TypeScript compiler and feed them to terser.
For me, I am able to map, by making sourcemap: "inline"
In the /build/index.esm.js file will have mapping inside.
export default {
input: "src/index.ts",
output: [
{
file: 'build/index.esm.js',
format: 'es',
sourcemap: "inline"
},
],
plugins: [
typescript({ sourceMap: false, inlineSources: true }),
]
}
I was having a similar issue with Karma, rollup, and typescript. I fixed it by adding "sourceRoot":"/base/" to my tsconfig.json file.
Before: map file entries pointed to /src/.
After: map file entries pointed to /base/src/ and everything worked.
// tsconfig.rollup.json
"compilerOptions": {
"module": "ES2022",
"esModuleInterop": true,
"target": "ES2022",
"moduleResolution": "classic",
"sourceMap": true,
"sourceRoot": "/base/"
...
}
// rollup.config.js
import typescript from '#rollup/plugin-typescript';
export default [
{
input: './src/test/test_context.spec.ts',
output: {
file: './dist/test/test_context.spec.js',
format: 'es',
sourcemap: 'inline'
},
plugins: [
typescript({
tsconfig: './tsconfig.rollup.json'
})
]
}
];

Rollup config for React component library not working with SSR

I'm trying to set up a React component library using Rollup, which my React app then installs and uses. The consuming React application is being rendered on the server. I have managed to get this set up working with Webpack, wherein I'm bundling my React component library into one single file and sending it down. Problem is this is a huge file and negates the point of SSR (part of it at least) as it takes a long time to download.
So I decided to use Rollup to split up the components into individual ES modules which are then pulled in and used as required by the app. The problem is that I can't get this to work with SSR at all. This is my first time using Rollup so I may have missed something obvious. Here is my rollup.config.js
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import css from 'rollup-plugin-css-only';
import alias from '#rollup/plugin-alias';
import image from '#rollup/plugin-image';
import json from '#rollup/plugin-json';
import replace from '#rollup/plugin-replace';
import namedDeps from './named-dependencies';
import stylus from './rollup-plugin-stylus-v2';
import postcssUrl from './rollup-plugin-postcss-url';
import autoExternal from 'rollup-plugin-auto-external';
import url from '#rollup/plugin-url';
import fs from 'fs';
const namedDepsObject = namedDeps
.map(depPath => ({
keys: Object.keys(require(depPath)).filter(v => v !== 'default'),
name: depPath,
}))
.reduce((acc, val) => {
acc[val.name] = val.keys;
return acc;
}, {});
let ComponentsList = require('./components-file'); // This has an array of component src and name
const rollConfigObject = fileName => {
const configOpts = {
input: `${fileName.src}`,
output: [
{
file: `dist/ssr/esm/${fileName.name}.js`,
format: 'esm',
}
],
plugins: [
autoExternal(),
url({
include: ['**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif', '**/*.woff', '**/*.woff2', '**/*.eot', '**/*.ttf', ],
emitFiles: false
}),
babel({
exclude: 'node_modules/**',
presets: ['#babel/env', '#babel/react'],
plugins: ['#babel/plugin-syntax-dynamic-import'],
runtimeHelpers: true,
}),
resolve(),
commonjs({
sourceMap: false,
namedExports: {
...namedDepsObject,
},
}),
image(),
json(),
stylus(),
postcssUrl(),
css({
output: function(styles, styleNodes){
fs.appendFileSync(__dirname + '/dist/ssr/styles.css', styles);
}
}),
],
};
return { ...configOpts };
};
export default ComponentsList.map(
moduleName => {
return rollConfigObject(moduleName);
}
)
Now this creates the separate component bundles like I want, but the problem is that it seems to be including code within the createCommonjsModule methods from node_modules which is then injecting browser objects like document, which when I attempt to render on the server throws an error.
I am trying to not include node_modules at all, so when I try to run this with only the babel plugin, it throws an Error: Could not resolve entry module and refuses to build. An example is Braintree, it's adding a lot of code with document usage.
I'm not sure how to get it to not inject node_modules code within the component. In the app, I'm using Webpack to run these modules through babel, but objects like document will pass through and then refuse to work on the server.
Any suggestions would be great here, been struggling with this for a number of days now. Thanks!
I got the config to work after I updated my babel setting to
babel({
exclude: [
'../../node_modules/**',
'../node_modules/**',
'node_modules/**',
],
presets: [
[
'#babel/env',
{
modules: false,
targets: {
esmodules: true,
},
},
],
'#babel/react',
],
plugins: [
'#babel/plugin-proposal-object-rest-spread',
'#babel/plugin-transform-runtime',
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-proposal-class-properties',
],
runtimeHelpers: true,
}),
commonjs({ sourceMap: false }),

How to build a component library using TypeScript, Ant Design and Rollup

I'm trying to create an example boilerplate for a library of reusable components in TypeScript, using Ant Design for UI elements and Rollup for bundling.
The Ant Design documentation although useful, doesn't give specific details for configuring Rollup and I've not had any luck finding an example using the same technology stack.
Using information from various online sources I've put together an outline boilerplate and published it to the following GitHub repository
However, the build output is showing a number of warnings from Rollup relating to rewriting references to 'this'. Can anyone suggest changes to my build config to resolve this issue?
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en#error-this-is-undefined
node_modules\antd\es\affix\index.js
6: import _inherits from "babel-runtime/helpers/inherits";
7: import _typeof from "babel-runtime/helpers/typeof";
8: var __decorate = this && this.__decorate || function (decorators, target, key, desc) {
^
9: var c = arguments.length,
10: r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
...
#Steve, I don't know if you already solved this problem, but I found a solution that worked for me using rollup-plugin-babel:
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import postcss from 'rollup-plugin-postcss';
import typescript from 'rollup-plugin-typescript2';
import url from 'rollup-plugin-url';
import pkg from './package.json';
const antdVars = require('./src/antd-vars');
export default {
input: 'src/index.tsx',
output: [
{
file: pkg.main,
format: 'cjs',
exports: 'named',
sourcemap: true,
},
{
file: pkg.module,
format: 'es',
exports: 'named',
sourcemap: true,
},
],
plugins: [
peerDepsExternal(),
url(),
nodeResolve({
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
}),
typescript({
exclude: ['*.d.ts', '**/*.d.ts', '**/*.story.tsx', '**/*.spec.tsx'],
rollupCommonJSResolveHack: true,
clean: true,
}),
babel({
babelrc: false,
plugins: [['import', { libraryName: 'antd', style: true }]],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
exclude: /\**node_modules\**/,
}),
commonjs({
include: /\**node_modules\**/,
}),
postcss({
extensions: ['.css', '.scss', '.less'],
use: ['sass', ['less', { javascriptEnabled: true, modifyVars: antdVars }]],
}),
],
};
The issue was resolve by updating the rollup config to mark the antd dependencies as external using rollup-plugin-peer-deps-external
The updated code can be seen in the Repo on GitHub

Categories