Is there a way for exporting multiple default react components from a react package in rollupjs? - javascript

I want to achieve to have multiple default exports. For example, if a react app installs my package named {my-package} then, they should be be able to import like
import Add from {my-package}/Add;
import Multiply from {my-package}/Multiple;
I've tried with making multiple end points in rollup.config.js.
`
export default [
{
input: files,
output: [
{
format: 'cjs',
strict: false,
// file: pkg.main,
dir: pkg.main,
sourcemap: true,
exports: 'named'
},
{
format: 'esm',
strict: false,
dir: pkg.module,
sourcemap: true,
exports: 'named'
}
],
plugins: [
commonjs(),
nodePolyfills(),
nodeResolve({ browser: true }),
image(),
json(),
postcss({
config: {
path: './postcss.config.js'
},
extensions: ['.css', '.scss'],
minimize: true,
inject: {
insertAt: 'top'
},
plugins: [url({ url: 'inline', maxSize: 10, fallback: 'copy' })]
}),
babel({ exclude: 'node_modules/**', presets: ['#babel/preset-react'] }),
typescriptPlugin({
objectHashIgnoreUnknownHack: true,
tsconfig: './tsconfig.json'
}),
cleaner({ targets: ['./dist/'] })
],
external: [
'react',
'react-dom',
'js-beautify',
'next-themes',
'react-split',
'react-codemirror2',
'react-responsive-modal',
'pinterpolate'
]
}
];
`
This is my rollup.config.js
Is it possible witn rollupjs?

Related

Rollup library ERROR in resolving fallback for shared module react

I am creating a design system library with rollup and React 17.0.1, unfortunatelly I am getting this error when I use the library
Error: Can't resolve 'react/jsx-runtime'
The rollup file is this
export default [
{
input: "src/index.ts",
output: [
{
file: packageJson.main,
format: "cjs",
exports: "auto",
sourcemap: false,
preserveModules: false
},
{
file: packageJson.module,
format: 'esm',
sourcemap: false
}
],
plugins: [
svgr(),
json(),
url(),
peerDepsExternal(),
resolve({
jsnext: true,
main: true,
browser: true
}),
babel({
babelrc: true,
exclude: 'node_modules/**',
presets: [
["#babel/preset-react", { runtime: "automatic" }],
]
}),
commonjs({
include: "node_modules/**",
namedExports: {
'styled-components': [ 'styled', 'css', 'ThemeProvider' ],
"react/jsx-runtime": ["jsx", "jsxs", "Fragment"],
"react/jsx-dev-runtime": ["jsxDEV", "Fragment"]
}
}),
typescript({ useTsconfigDeclarationDir: true }),
postcss(),
progress(),
visualizer({})
],
external: [...Object.keys(packageJson.peerDependencies || {})]
},
{
input: 'types/index.d.ts',
output: [{ file: 'dist/index.d.ts', format: "esm" }],
external: [/\.css$/],
plugins: [dts()],
},
]
I looked for lots of solutions but I cannot find any good one... may you help me? Thanks
Lorenzo
It may help. "#rollup/plugin-node-resolve" plugin.
resolve({ extensions: [".js", ".jsx"] })
(tsx and ts if you are using typescript)
please let me know if it didnt help :)

Read the contents of the module file/stream into a BLOB

I create a BLOB file and write JavaScipt code there, then create a URL and import the module from it.
const myJSFile = new Blob( [ 'export default true;' ], { type: 'application/javascript' } );
const myJSURL = URL.createObjectURL( myJSFile );
import( myJSURL ).then(async ( module ) => {
console.log( module.default );
});
This works great in the browser console. However, I am having a problem when building a project using Webpack.
I suspect the problem is with WebPack or Babel configuration.
Webpack common config:
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require("copy-webpack-plugin");
module.exports = {
// Where webpack looks to start building the bundle
entry: [
'core-js/modules/es6.promise',
'core-js/modules/es6.array.iterator',
'./src/main.js',
],
target: 'web',
// Where webpack outputs the assets and bundles
output: {
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: '[name].[contenthash].[ext]',
filename: '[name].[contenthash].bundle.js',
chunkFilename: '[id].[chunkhash].bundle.js',
// publicPath: '/',
},
// Determine how modules within the project are treated
module: {
rules: [
{
test: /\.(gif|png|jpe?g)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'assets/images/'
}
}
]
},
// JavaScript: Use Babel to transpile JavaScript files
{ test: /\.js$/, use: ['babel-loader'] },
// Images: Copy image files to build folder
{ test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: 'asset/resource' },
// Fonts and SVGs: Inline files
{ test: /\.(woff(2)?|eot|ttf|otf|svg|)$/, type: 'asset/inline' },
],
},
// Customize the webpack build process
plugins: [
// Generates an HTML file from a template
new HtmlWebpackPlugin({
// template: path.resolve(__dirname, 'src/index.html'), // шаблон
template: 'src/index.html',
// filename: 'index.html', // название выходного файла
// inject: false, // true, 'head'
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
},
// chunks: 'all',
// excludeChunks: [],
}),
new CopyWebpackPlugin(
{
patterns: [
{ from: 'src/assets', to: 'assets' },
// { from: 'src/components', to: 'components' },
]
}
),
],
resolve: {
// modules: [path.resolve(__dirname, 'src'), 'node_modules'],
extensions: ['.js', '.jsx', '.json', '.ts'],
alias: {
'#': [
path.resolve(__dirname, 'src'),
'./src/main.js'
],
},
},
}
Babel config
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
esmodules: true,
},
},
],
],
plugins: [
'#babel/plugin-proposal-class-properties',
'#babel/plugin-transform-runtime',
"#babel/plugin-syntax-dynamic-import"
]
};
I've used require-from-string before, which internally uses the native Module module to achieve this.
Speaking generally, Blobs don't really interoperate well between browser and node land, and modules are also not treated identically.. so it's not a surprise that blob+module has problems. :)

Jest won't transform node_module dependencies

Our code references the #myScope/vue-notify library which is set as a external/global in our rollup config. That code is an ES6 module and needs to be transpiled for jest to be able to work with it but by default Jest doesn't transpile node_modules folder. I have tried adding a negative lookahead to the transformIgnorePatterns but no matter what combination I try I just keep getting this error:
My Jest transform settings are as follows:
transform: {
'.+\\.(css|css!|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
'^.+\\.(js|jsx)?$': 'babel-jest',
},
transformIgnorePatterns: [
'/node_modules/(?!#myScope/vue-notify)',
'/dist/',
'/docs/',
],
My rollup.config.js is as follows:
import packageJson from './package.json';
import json from '#rollup/plugin-json';
import babel from '#rollup/plugin-babel';
import { addMinExtension } from './utils/utils';
import { terser } from 'rollup-plugin-terser';
import { nodeResolve } from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
const globals = {
DevExpress: 'DevExpress',
jquery: '$',
'#myScope/vue-notify': 'vueNotify',
'file-saver': 'saveAs',
exceljs: 'ExcelJS',
};
const externals = ['jquery', '#myScope/vue-notify', 'file-saver', 'exceljs'];
export default [
{
// Dev UMD Config:
input: packageJson.input,
output: [
{
name: packageJson.moduleName,
file: packageJson.browser,
format: 'umd',
globals: globals,
},
],
external: externals,
plugins: [
nodeResolve(),
commonjs({
include: 'node_modules/**',
}),
json(),
babel({ babelHelpers: 'runtime' }),
],
},
{
// Dev Module Config:
input: packageJson.input,
output: [
{
file: packageJson.module,
format: 'es',
},
],
external: externals,
plugins: [
nodeResolve(),
commonjs({
include: 'node_modules/**',
}),
json(),
],
},
{
// Prod UMD Config:
input: packageJson.input,
output: [
{
name: packageJson.moduleName,
file: addMinExtension(packageJson.browser),
format: 'umd',
sourcemap: true,
globals: globals,
},
],
external: externals,
plugins: [
nodeResolve(),
commonjs({
include: 'node_modules/**',
}),
json(),
babel({ babelHelpers: 'runtime' }),
terser(),
],
},
{
// Prod Module Config:
input: packageJson.input,
output: [
{
file: addMinExtension(packageJson.module),
format: 'es',
},
],
external: externals,
plugins: [
nodeResolve(),
commonjs({
include: 'node_modules/**',
}),
json(),
terser(),
],
},
];
Any help getting this working would be much appriciated!

ReferenceError: regeneratorRuntime is not defined

I'm using rollup to build a module from my project, and it's not including regeneratorRuntime. What am I missing here?
module.exports = {
external: [],
entry: './src/appProxypass/index.js',
dest: './packages/proxypass-app/index.js',
format: 'cjs',
plugins: [
require('rollup-plugin-commonjs')({
}),
require('rollup-plugin-babel')({
babelrc: false,
runtimeHelpers: true,
// externalHelpers: true,
'presets': [
'es2015-rollup',
'stage-2'
],
'plugins': [
'transform-async-to-generator',
'syntax-async-functions',
'transform-flow-strip-types',
'transform-class-properties'
],
exclude: 'node_modules/**'
}),
require('rollup-plugin-cleanup')()
]
}

Webpack babel config for both server and client javascript?

I'm trying to figure out how to have a single webpack config file that works for transforming both server (node.js) js and client js with the es2015 preset. Currently I have to specifically set "target: 'node'" for it to correctly process node-based files. If I don't, then webpack does the transformation based on the default "target: 'web'". It then reports errors because the 'mysql' module being imported clearly won't work for web.
How can I unify both into the same config file so that server and client js will be transformed separately? Or do I need separate configs entirely?
Sample webpack.config.js
'use strict';
var path = require('path');
var webpack = require('webpack');
module.exports = {
target: 'node',
resolve: {
root: path.resolve(__dirname),
extensions: ['', '.js']
},
entry: [
'babel-polyfill',
'./index.js',
],
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015']
}
}
]
}
};
Sample js code
import 'babel-polyfill';
import mysql from 'mysql';
class Test {
constructor () {
}
get read () {
}
};
You can pass multiple configs for Webpack to process at the same time. Simply return an array of configuration objects.
export default [
{
// config 1 here
},
{
// config 2 here
},
];
Extra tip: if you use .babel.js as extension for your config file, Webpack will run it through Babel for you, which allows you to use ES6 in your Webpack config.
Bonus: the snippet below
// Source: https://gist.github.com/Ambroos/f23d517a4261e52b4591224b4c8df826
import webpack from 'webpack';
import path from 'path';
import CleanPlugin from 'clean-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import AssetsPlugin from 'assets-webpack-plugin';
import CompressionPlugin from 'compression-webpack-plugin';
import autoprefixer from 'autoprefixer';
import rucksack from 'rucksack-css';
import cssnano from 'cssnano';
import moment from 'moment';
const sharedPlugins = [
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /nl/),
new webpack.optimize.AggressiveMergingPlugin({}),
new webpack.optimize.OccurenceOrderPlugin(true),
new webpack.optimize.UglifyJsPlugin({
compress: {
drop_console: true,
screw_ie8: true,
sequences: true,
properties: true,
dead_code: true,
drop_debugger: true,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: true,
if_return: true,
join_vars: true,
cascade: true,
negate_iife: true,
hoist_funs: true,
warnings: false,
},
mangle: {
screw_ie8: true,
},
output: {
screw_ie8: true,
preamble: '/* Website - ' + moment().format() + ' */',
},
}),
];
const sharedServerPlugins = [
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /nl/),
new webpack.optimize.AggressiveMergingPlugin({}),
new webpack.optimize.OccurenceOrderPlugin(true),
new webpack.optimize.UglifyJsPlugin({
compress: {
drop_console: false,
screw_ie8: true,
sequences: true,
properties: true,
dead_code: true,
drop_debugger: false,
conditionals: true,
comparisons: true,
evaluate: true,
booleans: true,
loops: true,
unused: true,
if_return: true,
join_vars: true,
cascade: true,
negate_iife: true,
hoist_funs: true,
warnings: false,
},
mangle: {
screw_ie8: true,
},
output: {
screw_ie8: true,
preamble: '/* Website - ' + moment().format() + ' */',
},
}),
];
const PATHS = {
build: path.resolve(__dirname, '..', 'build'),
sourcemaps: path.resolve(__dirname, '..', 'build', 'sourcemaps'),
browserSource: path.resolve(__dirname, '..', 'src', 'browser', 'index.js'),
browserBuild: path.resolve(__dirname, '..', 'build', 'browser'),
serverSource: path.resolve(__dirname, '..', 'src', 'server', 'index.js'),
serverAssetsSource: path.resolve(__dirname, '..', 'src', 'server', 'assets', 'index.js'),
serverBuild: path.resolve(__dirname, '..', 'build', 'server'),
};
export default [
// Browser
{
entry: { browser: PATHS.browserSource },
output: {
path: PATHS.browserBuild,
filename: 's/[chunkhash].js',
chunkFilename: 's/async-[chunkhash].js',
publicPath: '/',
sourceMapFilename: '../sourcemaps/browser/[file].map',
},
devtool: 'hidden-source-map',
plugins: [
new AssetsPlugin({
prettyPrint: true,
path: path.resolve(PATHS.build, 'browserAssets'),
filename: 'index.js',
processOutput: assets => `module.exports = ${JSON.stringify(assets, null, ' ')};`,
}),
new CleanPlugin([PATHS.browserBuild, PATHS.sourcemaps], path.resolve(PATHS.build, 'browserAssets')),
new ExtractTextPlugin('s/[contenthash].css'),
new CompressionPlugin({
asset: '{file}.gz',
algorithm: 'gzip',
regExp: /\.js$|\.html$|\.css$|\.svg$|\.eot$|\.xml$/,
threshold: 1400,
minRation: 0.8,
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
WEBPACK_ENV: JSON.stringify('browser'),
APP_ENV: (process.env.APP_ENV && JSON.stringify(process.env.APP_ENV)) || undefined,
},
}),
].concat(sharedPlugins),
externals: [
{ browserConfig: 'var websiteBrowserConfig' },
{ programs: 'var programs' },
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
},
{
test: /\.json$/,
loader: 'json',
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract(
'style',
[
'css?importLoaders=2&localIdentName=css-module-[hash:base64]',
'postcss',
'sass',
]
),
},
{
test: /\.(gif|png|jpe?g|svg|ico)$/i,
loaders: [
'url?limit=1400&name=s/i/[sha512:hash:base64:16].[ext]',
'image-webpack?bypassOnDebug',
],
},
{
test: /isotope\-|fizzy\-ui\-utils|desandro\-|masonry|outlayer|get\-size|doc\-ready|eventie|eventemitter/,
loader: 'imports?define=>false&this=>window',
},
{
test: /flickity/,
loader: 'imports?define=>false&this=>window',
},
{
test: /node_modules\/unipointer/,
loader: 'imports?define=>undefined',
},
],
},
postcss: () => {
return [rucksack, autoprefixer, cssnano];
},
},
// Server assets
{
entry: { assets: PATHS.serverAssetsSource },
target: 'node',
output: {
path: PATHS.browserBuild,
libraryTarget: 'commonjs',
filename: '../serverAssets/index.js',
publicPath: '/',
},
plugins: [
// assetsWriter,
new CompressionPlugin({
asset: '{file}.gz',
algorithm: 'gzip',
regExp: /\.js$|\.html$|\.css$|\.svg$|\.eot$|\.xml$/,
threshold: 1400,
minRation: 0.8,
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
WEBPACK_ENV: JSON.stringify('assets'),
APP_ENV: (process.env.APP_ENV && JSON.stringify(process.env.APP_ENV)) || undefined,
},
}),
].concat(sharedPlugins),
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
},
{
test: /\.json$/,
loader: 'json',
},
{
test: /\.(gif|png|jpe?g|svg|ico)$/i,
loaders: [
'url?limit=1400&name=s/i/[sha512:hash:base64:16].[ext]',
'image-webpack?bypassOnDebug',
],
},
],
},
},
// Server
{
entry: PATHS.serverSource,
target: 'node',
output: {
path: PATHS.build,
libraryTarget: 'commonjs',
filename: 'server/server.js',
publicPath: '/s/',
sourceMapFilename: 'sourcemaps/browser/[file].map',
},
externals: [
{ serverAssets: '../serverAssets/index.js' },
{ browserAssets: '../browserAssets/index.js' },
{ vrtConfig: '../../env_vars.js' },
/^(?!\.|\/).+/i,
/webpack-assets\.json/,
],
plugins: [
new CleanPlugin(PATHS.serverBuild),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
WEBPACK_ENV: JSON.stringify('server'),
APP_ENV: (process.env.APP_ENV && JSON.stringify(process.env.APP_ENV)) || undefined,
},
}),
].concat(sharedServerPlugins),
node: {
__dirname: false,
__filename: false,
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
},
{
test: /\.json$/,
loader: 'json',
},
],
},
},
];
That is the config we use in one of our sites with a partially shared codebase, and partially shared assets. It consists of three Webpack builds in one:
Browser
Server assets (images/fonts/... that will be referenced in server-generated HTML)
Server code (Node)
The server code has a few special properties:
target: 'node' (Webpack needs this)
output.libraryTarget: 'commonjs' (makes Webpack use commonjs for unbundled libs)
externals: [ /^(?!\.|\/).+/i, ] (makes Webpack not bundle anything in node_modules, or anything that is not a relative path (starting with . or /)
This combination makes Webpack only process your own code, and access other modules and libraries through require. Which means your dependencies using native bindings won't break as they won't be bundled.

Categories

Resources