I have a React project which I migrated from Babel 6 to 7. And now I'm facing a little problem when trying to build my package.
I already figured out the problem is when the Babel commands are run.
This is my "babel" script on my package.json:
"babel-build": "cross-env NODE_ENV=buildES6 babel ./src/components/ --ignore **/stories,**/*.test.js --source-maps --out-dir ./dist/my-component/"
This convert my files to dist folder. The problem is: when I try to use the dist folder content in another react project, it seems the files aren't correctly converted.
On my packaged project I export 3 components like this (my src/components/index.js file):
export { FancyButton } from './FancyPanel/FancyButton';
export { MathUtils } from './FancyPanel/MathUtils';
export { SumPanel } from './FancyPanel/SumPanel';
And on the another project I use my component like this (I copied the dist folder to the node_modules folder of this project to simulate the installation of my package):
import React from 'react';
import { FancyButton, MathUtils, SumPanel } from 'my-component';
class Home extends React.Component {
constructor() {
super();
}
render()
{
return (
<div>
<FancyButton
className="fancyBt"
id="myFancyBt"
text="Click me!"
title="Button to click on"
onClick={() => {alert('clicked')}}
/>
Random number: {MathUtils.getRandomArbitrary(1, 10)}
<SumPanel/>
</div>
);
}
}
export default Home;
And the browser says:
TypeError: Cannot read property 'getRandomArbitrary' of undefined
I think my converted index.js should be:
import _FancyButton from'./FancyPanel/FancyButton';export{_FancyButton as FancyButton};import _MathUtils from'./FancyPanel/MathUtils';export{_MathUtils as MathUtils};import _SumPanel from'./FancyPanel/SumPanel';export{_SumPanel as SumPanel};
But it is converted like this:
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"FancyButton",{enumerable:!0,get:function get(){return _FancyButton.FancyButton}}),Object.defineProperty(exports,"MathUtils",{enumerable:!0,get:function get(){return _MathUtils.MathUtils}}),Object.defineProperty(exports,"SumPanel",{enumerable:!0,get:function get(){return _SumPanel.SumPanel}});var _FancyButton=require("./FancyPanel/FancyButton"),_MathUtils=require("./FancyPanel/MathUtils"),_SumPanel=require("./FancyPanel/SumPanel");
//# sourceMappingURL=index.js.map
I think I'm not configuring well my babel.config.js. But I already tried many ways and the problem remains.
Here's my babel.config.js:
/* eslint-disable no-template-curly-in-string */
module.exports = {
plugins:
[
[
'#babel/plugin-transform-runtime',
{
corejs: false
}
],
'#babel/plugin-transform-modules-commonjs',
[
'transform-imports',
{
lodash: {
transform: 'lodash/${member}'
}
}
]
],
env: {
production: {
plugins: [
'transform-react-remove-prop-types'
]
},
test: {
presets: [
[
'#babel/preset-env'
],
'#babel/react'
]
},
commonJS: {
presets: [
[
'#babel/preset-env'
],
'#babel/react'
]
},
buildES6: {
presets: [
[
'#babel/env',
{
modules: false,
loose: true
}
],
'#babel/react',
[
'minify',
{
mangle: false
}
]
],
plugins: [
'#babel/plugin-proposal-class-properties'
]
}
}
};
Anyone can help me fixing it? What is the problem?
Here is my source code (without this last babel config version): https://github.com/Ninita1/storybook5_babel7_webpack4
My package.json:
"scripts": {
"babel-build": "cross-env NODE_ENV=buildES6 babel ./src/components/ --ignore **/stories,**/*.test.js --source-maps --out-dir ./dist/my-component/"
},
"dependencies": {
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"prop-types": "^15.7.2",
"react": "^16.9.0",
"react-dom": "^16.9.0"
},
"devDependencies": {
"#babel/cli": "7.8.3",
"#babel/core": "7.8.3",
"#babel/plugin-proposal-class-properties": "7.8.3",
"#babel/plugin-transform-runtime": "7.8.3",
"#babel/preset-env": "7.8.3",
"#babel/preset-react": "7.8.3",
"#storybook/addon-docs": "5.3.9",
"#storybook/react": "5.3.9",
"babel-eslint": "^10.0.3",
"babel-jest": "^24.9.0",
"babel-loader": "^8.0.6",
"babel-minify": "^0.5.1",
"babel-plugin-transform-imports": "^2.0.0",
"clean-webpack-plugin": "^0.1.17",
"copy-webpack-plugin": "^4.5.3",
"cross-env": "^7.0.0",
"css-loader": "^3.4.2",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"enzyme-to-json": "^3.4.0",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-loader": "^2.1.2",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.14.3",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^5.0.2",
"jest": "^24.9.0",
"jest-html-reporters": "^1.2.1",
"js-beautify": "^1.10.2",
"lodash": "^4.17.15",
"marksy": "^8.0.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"raw-loader": "^4.0.0",
"react-addons-create-fragment": "^15.6.2",
"react-test-renderer": "^16.9.0",
"resolve-url-loader": "^3.1.1",
"style-loader": "^1.1.3",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "4.41.5",
"webpack-cli": "^3.3.10"
}
I already figured out.
I should change my index.js to this:
import FancyButton from './FancyPanel/FancyButton';
import MathUtils from './FancyPanel/MathUtils';
import SumPanel from './FancyPanel/SumPanel';
export { FancyButton, MathUtils, SumPanel };
I tried many babel.config.js modifications and at the end I only have this:
/* eslint-disable no-template-curly-in-string */
module.exports = {
presets: [
'#babel/preset-env',
'#babel/preset-react'
],
plugins:
[
'#babel/plugin-proposal-class-properties',
'#babel/plugin-transform-modules-commonjs'
]
};
But with #nicolo-ribaudo help at https://github.com/babel/babel/issues/11107 I figured out that #babel/plugin-transform-modules-commonjs plugin shouldn't be declared and #babel/env preset must have modules: false, like this:
/* eslint-disable no-template-curly-in-string */
module.exports = {
presets: [
[
'#babel/env',
{
modules: false
}
],
'#babel/react'
],
plugins: [
'#babel/plugin-proposal-class-properties'
]
};
Now my babel.config.js looks like this and works just fine (for npm run babel-build);
/* eslint-disable no-template-curly-in-string */
module.exports = {
presets: [
[
'#babel/env',
{
modules: false,
loose: true
}
],
'#babel/react',
[
'minify',
{
mangle: false
}
]
],
plugins: [
'#babel/plugin-proposal-class-properties',
[
'#babel/plugin-transform-runtime',
{
corejs: false
}
],
[
'transform-imports',
{
lodash: {
transform: 'lodash/${member}'
}
}
]
]
};
For npm run build my babel.config.js must be:
/* eslint-disable no-template-curly-in-string */
module.exports = {
plugins:
[
[
'#babel/plugin-transform-runtime',
{
corejs: false
}
],
[
'transform-imports',
{
lodash: {
transform: 'lodash/${member}'
}
}
]
],
env: {
production: {
plugins: [
'transform-react-remove-prop-types'
]
},
test: {
presets: [
'#babel/env',
'#babel/react'
],
plugins: [
'#babel/plugin-transform-modules-commonjs'
]
},
commonJS: {
presets: [
'#babel/env',
'#babel/react'
]
},
buildES6: {
presets: [
[
'#babel/env',
{
modules: false,
loose: true
}
],
'#babel/react',
[
'minify',
{
mangle: false
}
]
],
plugins: [
'#babel/plugin-proposal-class-properties'
]
}
}
};
Related
Please help me out to solve a problem. I'm making my library for react apps using styled-components, react, storybook. Also have babel config and rollup for bundling. I'm really not sure about babel and rollup configs cuz I'm setting them myself for the first time.
When I'm checking how the lib works via storybook all is fine. But when I publish it on npm and trying to use it in another react project, created via npx create-react-app I'm constantly getting and error "TypeError: Cannot read properties of undefined (reading 'withConfig')" in console and my app doesn't show anything.
Here you can see my .babelrc:
{
"env": {
"development": {
"plugins": [
[
"babel-plugin-styled-components",
{ "ssr": true, "displayName": true, "preprocess": false }
],
[
"module-resolver",
{
"alias": {
"#src": ["./src"],
"#components": ["./src/components"],
"#utils": ["./src/utils"]
}
}
]
],
"presets": ["#babel/preset-react", "#babel/preset-env"]
},
"production": {
"plugins": [
[
"babel-plugin-styled-components",
{ "ssr": true, "displayName": true, "preprocess": false }
]
],
"presets": ["#babel/preset-react", "#babel/preset-env"]
}
},
"plugins": [
[
"styled-components",
{ "ssr": true, "displayName": true, "preprocess": false }
]
]
}
rollup.config.json:
import babel from '#rollup/plugin-babel';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import resolve from '#rollup/plugin-node-resolve';
import alias from '#rollup/plugin-alias';
import { terser } from 'rollup-plugin-terser';
import commonjs from '#rollup/plugin-commonjs';
export default [
{
input: './src/index.js',
external: [
'react',
'react-dom',
'styled-components',
'prop-types',
'react-icons',
],
output: [
{
file: 'dist/index.js',
format: 'cjs',
},
{
file: 'dist/index.es.js',
format: 'es',
exports: 'named',
},
],
plugins: [
peerDepsExternal(),
resolve(),
alias({
resolve: ['.js', '.ts', '.tsx', '.jsx'],
entries: [
{
find: '#src',
replacement: './src',
},
{
find: '#components',
replacement: './src/components',
},
{
find: '#utils',
replacement: './src/utils',
},
],
}),
resolve({
extensions: ['.js', '.jsx', '.mjs', '.json'],
browser: true,
}),
babel({
exclude: 'node_modules/**',
plugins: [
[
'babel-plugin-styled-components',
{ ssr: true, displayName: true, preprocess: false },
],
[
'module-resolver',
{
alias: {
'#src': ['./src'],
'#components': ['./src/components'],
'#utils': ['./src/utils'],
},
},
],
],
presets: ['#babel/preset-react', '#babel/preset-env'],
babelHelpers: 'bundled',
}),
commo.njs(),
terser(),
],
},
];
package.json:
"description": "",
"main": "dist/index.js",
"module": "dist/index.mjs",
"devDependencies": {
"#babel/cli": "^7.19.3",
"#babel/core": "^7.20.2",
"#babel/preset-env": "^7.20.2",
"#babel/preset-react": "^7.18.6",
"#cypress/react": "^7.0.1",
"#rollup/plugin-alias": "^4.0.2",
"#rollup/plugin-babel": "^6.0.2",
"#rollup/plugin-commonjs": "^23.0.2",
"#rollup/plugin-node-resolve": "^15.0.1",
"#storybook/addon-actions": "^6.5.13",
"#storybook/addon-essentials": "^6.5.13",
"#storybook/addon-interactions": "^6.5.13",
"#storybook/addon-links": "^6.5.13",
"#storybook/builder-webpack4": "^6.5.13",
"#storybook/manager-webpack4": "^6.5.13",
"#storybook/react": "^6.5.13",
"#storybook/testing-library": "^0.0.13",
"#storybook/testing-react": "^1.3.0",
"babel-loader": "^8.3.0",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-styled-components": "^2.0.7",
"cypress": "^11.2.0",
"eslint": "8.2.0",
"eslint-config-airbnb": "19.0.4",
"eslint-plugin-import": "2.25.3",
"eslint-plugin-jsx-a11y": "6.5.1",
"eslint-plugin-react": "7.28.0",
"eslint-plugin-react-hooks": "4.3.0",
"prettier": "2.7.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.6.0",
"rollup": "^3.4.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-terser": "^7.0.2",
"styled-components": "^5.3.6"
},
"peerDependencies": {
"prop-types": ">=15.8.1",
"react": ">=18.2.0",
"react-dom": ">=18.2.0",
"react-icons": ">=4.6.0",
"styled-components": ">=5.3.6"
},
"resolutions": {
"styled-components": "^5"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"build": "rollup -c --bundleConfigAsCjs",
"test:cypress": "cypress open"
},
"author": "Victoria",
"license": "ISC",
"dependencies": {}
}
I tried changing my babel and rollup configs, not using "babel-plugin-styled-components" and it did cause another error "e.div is not a fucntion". As I undrestood myself not using this plugin cause it (I might be wrong). So I started using "babel-plugin-styled-components" and now I'm having this issue.
I would be really greatfull if somebody could help me out here.
Background
Need to create an external React component library using existing components from a Next.js site, using Tailwindcss#^2. This needs to be pulled in using npm, onto any site that requires the components.
Problem
I've managed to create the package using Webpack#^5 to compile. This is all fine, but the problem I face is that, the components don't work when reintroduced to the initial site. I have a feeling this is either the compiling is wrong or the fact that Next.js is server side rendered, or it could be both.
Attempted solution
I have tried to use Rollup as an alternate solution to compile the components, but I keep running into an issue with Postcss. A common issue I've noticed, where it's asking for v8 of PostCss (which it appears is present in node_modules), but it still complains. I did have a similar issue when using Webpack, but was eventually able to fix this. I've tried similar methods to fix for Rollup, but no luck.
package.json
{
"name": "#github_account/package_name",
"description": "Lorem ipsum",
"author": "github_account",
"version": "1.0.0",
"license": "ISC",
"repository": {
"type": "git",
"url": "repo_name_here"
},
"main": "./build/main.cjs.js",
"module": "./build/main.esm.js",
"browser": "./build/main.js",
"source": "./src/index.js",
"publishConfig": {
"registry": "https://npm.pkg.github.com/github_account"
},
"scripts": {
"build-rollup": "rollup -c",
"build": "webpack --mode production"
},
"dependencies": {
"#babel/runtime": "^7.17.8",
"autoprefixer": "^9.8.8",
"classnames": "^2.2.6",
"formik": "^2.2.6",
"iframe-resizer-react": "^1.1.0",
"luxon": "^2.0.2",
"prop-types": "^15.8.1",
"react": "^17.0.0",
"react-collapsible": "^2.8.4",
"react-device-detect": "^2.1.2",
"react-dom": "^17.0.0",
"react-google-recaptcha-v3": "^1.9.7",
"react-icons": "^3.10.0",
"react-markdown": "^6.0.3",
"react-modal": "^3.14.4",
"react-select": "^5.0.0",
"react-slick": "^0.28.1",
"react-table": "^7.7.0",
"sass": "^1.42.1",
"slick-carousel": "^1.8.1",
"yup": "^0.32.8"
},
"devDependencies": {
"#babel/core": "^7.18.6",
"#babel/plugin-syntax-jsx": "^7.18.6",
"#babel/plugin-transform-runtime": "^7.18.9",
"#babel/preset-env": "^7.18.6",
"#babel/preset-react": "^7.18.6",
"#rollup/plugin-babel": "^5.3.1",
"#rollup/plugin-commonjs": "^22.0.1",
"#rollup/plugin-node-resolve": "^13.3.0",
"#squoosh/lib": "^0.4.0",
"autoprefixer": "~9",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.2.5",
"clean-webpack-plugin": "^4.0.0",
"cross-env": "^7.0.2",
"css-loader": "^6.7.1",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.7.0",
"eslint-config-standard": "^14.1.0",
"eslint-config-standard-react": "^9.2.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-standard": "^4.0.1",
"image-minimizer-webpack-plugin": "^3.2.3",
"microbundle-crl": "^0.13.11",
"mini-css-extract-plugin": "^2.6.1",
"next": "^12.1.0",
"next-seo": "^4.28.1",
"npm-run-all": "^4.1.5",
"path": "^0.12.7",
"postcss": "8.4.6",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-import": "^14.1.0",
"postcss-loader": "^4.3.0",
"postcss-nested": "^5.0.6",
"postcss-preset-env": "^6.7.1",
"prettier": "^2.3.1",
"react-scripts": "^3.4.1",
"rollup": "^2.77.0",
"rollup-plugin-filesize": "^9.1.2",
"rollup-plugin-image": "^1.0.2",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-tailwindcss": "^1.0.0",
"sass-loader": "^12",
"tailwindcss": "^2.2.6",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-node-externals": "^3.0.0"
}
}
webpack.config.js
const path = require("path");
const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const stylesHandler = MiniCssExtractPlugin.loader;
module.exports = {
devtool: "source-map",
context: __dirname,
entry: "./src/index.js",
externals: [nodeExternals({ importType: "umd" })],
output: {
filename: "[name].js",
path: path.resolve(__dirname, "./dist"),
libraryTarget: "umd",
library: {
name: "cruil",
type: "umd",
},
assetModuleFilename: (pathData) => {
const filepath = path.dirname(pathData.filename).split("/").slice(1).join("/");
return `${filepath}/[name].[hash][ext][query]`;
},
globalObject: "this",
},
experiments: {
outputModule: true,
},
optimization: {
runtimeChunk: "single",
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
encodeOptions: {
pngquant: {
quality: 90,
},
},
},
},
}),
],
splitChunks: {
chunks: "all",
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm package names are URL-safe, but some servers don't like # symbols
return `npm.${packageName.replace("#", "")}`;
},
},
},
},
},
module: {
rules: [
{
test: /\.js$|jsx/,
include: path.resolve(__dirname, "./src"),
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
},
},
},
{
test: /\.(s(a|c)ss)$/,
use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"],
include: path.resolve(__dirname, "./src"),
},
{
test: /\.css$/i,
use: [stylesHandler, "css-loader", "postcss-loader"],
},
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
include: path.resolve(__dirname, "./src/assets"),
type: "asset/resource",
},
],
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin(),
new webpack.DefinePlugin({
"process.env": {
// This has effect on the react lib size
NODE_ENV: JSON.stringify("production"),
},
}),
],
};
rollup.config.js
import babel from "#rollup/plugin-babel";
import resolve from "#rollup/plugin-node-resolve";
import commonjs from "#rollup/plugin-commonjs";
import postcss from "rollup-plugin-postcss";
import filesize from "rollup-plugin-filesize";
import autoprefixer from "autoprefixer";
import image from "rollup-plugin-image";
import external from "rollup-plugin-peer-deps-external";
import replace from "rollup-plugin-replace";
import tailwind from "rollup-plugin-tailwindcss";
import pkg from "./package.json";
const INPUT_FILE_PATH = "src/index.js";
const OUTPUT_NAME = "main";
const GLOBALS = {
react: "React",
"react-dom": "ReactDOM",
"prop-types": "PropTypes",
};
const getBabelOptions = ({ useESModules }) => ({
babelrc: false,
exclude: "node_modules/**",
extensions: [".js", ".ts", ".jsx", ".tsx"],
babelHelpers: "runtime",
presets: [["#babel/preset-env", { modules: false }], "#babel/preset-react"],
plugins: [["#babel/transform-runtime", { regenerator: false, useESModules }], "#babel/plugin-syntax-jsx"],
});
const PLUGINS = [
external({
includeDependencies: true,
}),
image(),
tailwind({
input: "./src/styles/index.css",
purge: false,
}),
postcss({
extract: true,
modules: true,
plugins: [autoprefixer],
}),
resolve({
browser: true,
resolveOnly: [/^(?!react$)/, /^(?!react-dom$)/, /^(?!prop-types)/],
preferBuiltins: false,
}),
commonjs({
include: /node_modules/,
}),
replace({ "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) }),
babel(getBabelOptions({ useESModules: true })),
filesize(),
];
const EXTERNAL = ["react", "react-dom", "prop-types"];
// https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers
const CJS_AND_ES_EXTERNALS = EXTERNAL.concat(/#babel\/runtime/);
const OUTPUT_DATA = [
{
file: pkg.browser,
format: "umd",
},
{
file: pkg.main,
format: "cjs",
},
{
file: pkg.module,
format: "es",
},
];
const config = OUTPUT_DATA.map(({ file, format }) => ({
input: INPUT_FILE_PATH,
output: {
file,
format,
name: OUTPUT_NAME,
globals: GLOBALS,
},
external: ["cjs", "es"].includes(format) ? CJS_AND_ES_EXTERNALS : EXTERNAL,
plugins: PLUGINS,
}));
export default config;
postcss.config.js
module.exports = {
plugins: [
require("postcss-import"),
require("tailwindcss"),
require("postcss-flexbugs-fixes"),
require("postcss-nesting"),
require("postcss-custom-properties"),
require("autoprefixer"),
],
};
index.js
import "./styles/index.css";
import ExampleTestComponent from "./components/ExampleTestComponent";
...
export {
ExampleTestComponent,
...
}
ExampleTestComponent.js
import React from "react";
const ExampleTestComponent = (props) => {
return (
<div className="ExampleTestComponentClass">
--- This is a test ---
</div>
);
};
export default ExampleTestComponent;
index.css
#tailwind base;
#tailwind components;
#tailwind utilities;
Site Implementation
import ExampleTestComponent from "#github_account/package_name";
const HomePageTemplate = ({ heroItems, partners, newsItems, videos }) => {
const partnerItems = partners.map((partner) => ({
image: partner.logo,
url: partner.url,
}));
return (
<HomePageLayout heroItems={heroItems} partnerItems={partnerItems}>
<ExampleTestComponent />
<SuccessStoriesSlider videos={videos} />
<NewsBlock
newsItems={newsItems}
title="News"
subtitle="Latest news posts"
viewMoreBtnLabel="View Posts"
readMoreBtnLabel="Read More"
/>
</HomePageLayout>
);
};
export default HomePageTemplate;
UPDATE 1
Turns out a combination of using Yarn and adding the below
{
"resolutions": {
"postcss": "8"
}
}
to package.json, fixes the Postcss issue. So now I have the package created, I am attempting to import into the main site. However I'm now getting the error:
Error: Must use import to load ES Module: /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/defineProperty.js
require() of ES modules is not supported.
require() of /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/defineProperty.js from /node_modules/#github_account/package_name/build/main.cjs.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename defineProperty.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/package.json.
I want to add tailwind to storybook. So that Stories will render just like it will render on web.
I used create-react-app project-name --template typescript to create the project.
Then to install the tailwind I followed this https://tailwindcss.com/docs/guides/create-react-app instruction from the documentation of tailwind.
Once I finished it I ran the code npm sb init. Which made sure that storybook ran.
Now I need to tell storybook to use tailwindcss for styling. But I have no idea how.
Every other answer I saw tells to edit postcss.config.js files.
But I followed this https://tailwindcss.com/docs/guides/create-react-app documentation where I didnt even have to create postcss.config.js file. So I am confused to what to do now.
For clarity I will include some configuration file below.
craco.config.js
module.exports = {
style: {
postcss: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
}
.storybook/preview.js
import "../src/index.css"
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
}
.storybook/main.js
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/preset-create-react-app"
]
}
src/index.css
#tailwind base;
#tailwind components;
#tailwind utilities;
tailwind.config.js
module.exports = {
purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
package.json
`{
"name": "memory",
"version": "0.1.0",
"private": true,
"dependencies": {
"#craco/craco": "^6.0.0",
"#tailwindcss/postcss7-compat": "^2.0.2",
"#testing-library/jest-dom": "^5.11.4",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"#types/jest": "^26.0.15",
"#types/node": "^12.0.0",
"#types/react": "^16.14.2",
"#types/react-dom": "^16.9.8",
"autoprefixer": "^9.8.6",
"postcss": "^7.0.35",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.1",
"tailwindcss": "npm:#tailwindcss/postcss7-compat#^2.0.2",
"typescript": "^4.0.3",
"web-vitals": "^0.2.4"
},
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject",
"storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook -s public"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#storybook/addon-actions": "^6.1.11",
"#storybook/addon-essentials": "^6.1.11",
"#storybook/addon-links": "^6.1.11",
"#storybook/node-logger": "^6.1.11",
"#storybook/preset-create-react-app": "^3.1.5",
"#storybook/react": "^6.1.11"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
Storybook recommends using the #storybook/addon-postcss for customizing the postCSS config from now on (instead of relying on customizing the postcss-loader):
Add the postCSS addon to your installation
npm i -D #storybook/addon-postcss # or
yarn add -D #storybook/addon-postcss
Create the postcss.config.js in the project root
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
Add the plugin to your .storybook/main.js
// .storybook/main.js
module.exports = {
...
addons: [
...
{
name: '#storybook/addon-postcss',
options: {
cssLoaderOptions: {
// When you have splitted your css over multiple files
// and use #import('./other-styles.css')
importLoaders: 1,
},
postcssLoaderOptions: {
// When using postCSS 8
implementation: require('postcss'),
},
},
},
],
};
Import your css file in the .storybook/preview.js
// .storybook/preview.js
import '../src/styles.css';
You're almost there.
The missing piece of your config is to add a webpack configuration to apply tailwind to postcss-loader:
const path = require('path')
module.exports = {
stories: [
'../src/**/*.stories.mdx',
'../src/**/*.stories.#(js|jsx|ts|tsx)'
],
addons: [
'#storybook/addon-links',
'#storybook/addon-essentials',
'#storybook/preset-create-react-app',
],
webpackFinal: async (config) => {
config.module.rules.push({
test: /\.css$/,
use: [
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
},
],
include: path.resolve(__dirname, '../'),
})
return config
},
}
TAILWIND STORYBOOK CRA [2022-2023(hopefully)]
package.json
"devDependencies": {
"#storybook/addon-actions": "^6.5.9",
"#storybook/addon-essentials": "^6.5.9",
"#storybook/addon-interactions": "^6.5.9",
"#storybook/addon-links": "^6.5.9",
"#storybook/addon-postcss": "^2.0.0",
"#storybook/builder-webpack5": "^6.5.9",
"#storybook/manager-webpack5": "^6.5.9",
"#storybook/node-logger": "^6.5.9",
"#storybook/preset-create-react-app": "^4.1.2",
"#storybook/react": "^6.5.9",
"#storybook/testing-library": "^0.0.13",
"#typescript-eslint/eslint-plugin": "^5.28.0",
"#typescript-eslint/parser": "^5.28.0",
"autoprefixer": "^10.4.7",
"babel-plugin-named-exports-order": "^0.0.2",
"eslint": "^8.17.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"postcss": "^8.4.14",
"tailwindcss": "^3.1.1",
"webpack": "^5.73.0"
}
tailwind.config.js
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
.storybook/main.js
module.exports = {
stories: [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
addons: [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/addon-interactions",
"#storybook/preset-create-react-app",
{
name: '#storybook/addon-postcss',
options: {
postcssLoaderOptions: {
implementation: require('postcss'),
},
},
},
],
framework: "#storybook/react",
core: {
"builder": "#storybook/builder-webpack5"
}
}
.storybook/preview.js
import '!style-loader!css-loader!postcss-loader!tailwindcss/tailwind.css';
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
The answer was right but in the latest CRA I have to config like this:
config.module.rules.push({
test: /\.css$/,
use: [
{
loader: "postcss-loader",
options: {
// HERE: OPTIONS
postcssOptions: {
plugins: [require("tailwindcss"), require("autoprefixer")],
},
},
},
],
include: path.resolve(__dirname, "../"),
});
Similar to ofhouse's answer, but here is a solution if you don't want to have an extra postcss.config.js for only a few lines or if you want use typescript in everything (as the loader doesn't pick up postcss.config.ts)
Add the official postCSS addon
npm i -D #storybook/addon-postcss
yarn add -D #storybook/addon-postcss
Config main.ts & tailwind.config.ts
/* .stories/main.ts */
import postcss from 'postcss';
import * as tailwindcss from '../tailwind.config';
import type { StorybookConfig } from '#storybook/react/types';
export const addons: StorybookConfig['addons'] = [
// other addons,
{
name: '#storybook/addon-postcss',
options: {
postcssLoaderOptions: {
implementation: postcss,
postcssOptions: {
plugins: {
tailwindcss, // or you can nest your options entirely here
autoprefixer: {
// autoprefixer options
},
},
},
},
},
},
];
/* tailwind.config.ts */
import type { TailwindConfig } from 'tailwindcss/tailwind-config';
export const theme: TailwindConfig['theme'] = {
// theme options
}
// other options
This problem gave me headaches too. I followed every solution that can be found on StackOverflow and Github.
But I only could "fix it" by running the tailwind-CLI and building the global.css file and importing it to ./storybook/preview.js
here's the cli command used.
npx tailwindcss -i ./src/styles/global.css -o ./.storybook/global.css --watch
then import it from the output path (-o flag) in the command above.
// ./storybook/preview.js
import './global.css';
...
I've tried all the above answers but unfortunately, I was still getting some weird unknown word error when running the storybook.
This is the only solution that worked for me:
https://github.com/storybookjs/addon-postcss/issues/33#issuecomment-1173042151
I'm trying to set up Jest to test my app as it grows. I'm getting the below error:
SyntaxError: Unexpected identifier
> 1 | const screenSize = require("../src/index.js").screenSize;
| ^
I'm using Phaser 3, Webpack, Babel, and React.
I'm relatively new to all except React.
I followed Jest's Getting Started tutorial and using with webpack tutorial, but I'm still getting the error.
package.json
{
"name": "phaser3-project-template",
"version": "1.1.0",
"description": "A Phaser 3 Project Template",
"main": "src/index.js",
"scripts": {
"build": "webpack --config webpack/prod.js ",
"start": "webpack-dev-server --config webpack/base.js --open",
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/photonstorm/phaser3-project-template.git"
},
"author": "Richard Davey <rdavey#gmail.com> (http://www.photonstorm.com)",
"license": "MIT",
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
"bugs": {
"url": "https://github.com/photonstorm/phaser3-project-template/issues"
},
"homepage": "https://github.com/photonstorm/phaser3-project-template#readme",
"devDependencies": {
"#babel/core": "^7.4.3",
"#babel/plugin-proposal-class-properties": "^7.4.0",
"#babel/preset-env": "^7.4.3",
"#babel/preset-react": "^7.0.0",
"babel-jest": "^24.7.1",
"babel-loader": "^8.0.5",
"clean-webpack-plugin": "^1.0.0",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"jest": "^24.7.1",
"path": "^0.12.7",
"raw-loader": "^1.0.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"terser-webpack-plugin": "^1.2.1",
"webpack": "^4.28.3",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.14",
"webpack-merge": "^4.2.1"
},
"dependencies": {
"babel-core": "^6.26.3",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^2.1.1",
"phaser": "^3.16.2",
"react-redux": "^7.0.2",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"style-loader": "^0.23.1"
},
"jest": {
"modulePaths": [
"node_modules"
],
"moduleFileExtensions": [
"js",
"jsx"
],
"moduleDirectories": [
"node_modules"
],
"moduleNameMapper": {
"\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
"\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
}
}
}
webpack/base.js
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
mode: "development",
devtool: "eval-source-map",
entry: "./src/index.js", //do we need this?
output: {
path: path.resolve("dist"),
filename: "index_bundle.js"
},
module: {
rules: [
{
test: /\.css$/,
use: [{ loader: "style-loader" }, { loader: "css-loader" }]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: "babel-loader"
},
{
test: [/\.vert$/, /\.frag$/],
use: "raw-loader"
},
{
test: /\.(gif|png|jpe?g|svg|xml)$/i,
use: "file-loader"
}
]
},
plugins: [
new CleanWebpackPlugin(["dist"], {
root: path.resolve(__dirname, "../")
}),
new webpack.DefinePlugin({
CANVAS_RENDERER: JSON.stringify(true),
WEBGL_RENDERER: JSON.stringify(true)
}),
new HtmlWebpackPlugin({
template: "./index.html",
filename: "index.html",
inject: "body"
})
]
};
.babelrc.js
const presets = [
[
"#babel/env",
{
targets: {
browsers: [">0.25%", "not ie 11", "not op_mini all"],
node: "current"
},
modules: false
}
],
"#babel/preset-react"
];
const plugins = ["#babel/plugin-proposal-class-properties"];
module.exports = { presets, plugins };
jest.config.js
"use strict";
module.exports = {
testMatch: ["<rootDir>/**/*.test.js"],
testPathIgnorePatterns: ["/src/", "node_modules"]
};
index.test.js
const screenSize = require("../src/index.js").screenSize;
//import toBeType from "jest-tobetype";
console.log(screenSize);
test("screenSize is an object", () => {
expect(typeof screenSize).toBe("object");
});
Github Repo
How can I get Jest to process the es6 syntax?
Require is a node environment syntax for importing variables, and Jest runs in node. More background on the differences between import/require and node can be seen in this SO question
You can add support for this with
npm install --save-dev #babel/plugin-proposal-class-properties #babel/plugin-transform-modules-commonjs
and include these as presets in your babelrc.js
const presets = [
[
"#babel/env",
{
targets: {
browsers: [">0.25%", "not ie 11", "not op_mini all"]
},
modules: false
}
],
"#babel/preset-react"
];
const plugins = [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-modules-commonjs"
];
module.exports = { presets, plugins };
The above code will still run into a number of errors details to resolve those can be seen here: https://medium.com/#Tnodes/setting-up-jest-with-react-and-phaser-422b174ec87e
I'm having a different problem from the one here. babel-plugin-react-css-modules is not matching styles with styleName
I'm trying to search for the app class in my App.jsx file to confirm I've setup babel-plugin-react-css-modules with Enzyme. Unfortunately, I clearly haven't done so successfully, even though i seem to be following the supposed solution here: https://github.com/gajus/babel-plugin-react-css-modules/issues/168 (although I'm using Jest)
I'd really appreciate any help.
App.jsx
import React from 'react';
import { hot } from 'react-hot-loader/root';
import './App.css';
const App = () => (
<div styleName="App">
<h1>Hello World!</h1>
</div>
);
export default hot(App);
App.test.js
import {mount} from 'enzyme';
import React from 'react';
import App from './App';
it('has an App component which returns a div with the class named App', () => {
const wrapper = mount(<App />);
expect(wrapper.find('.app')).toHaveLength(1);
})
test failure message
Expected length: 1
Received length: 0
Received object: {}
I've confirmed that the issue is due to transpilation because the test passes when I search for the class App__App___1o-Fp which is what it appears as on localhost.
.babelrc
{
"env": {
"test": {
"presets": ["#babel/env", "#babel/preset-react"],
"plugins": [
[
"react-css-modules",
{
"generateScopedName": "[local]"
}]
]
}
},
"presets": ["#babel/env", "#babel/preset-react"],
"plugins": ["react-hot-loader/babel", [
"react-css-modules",
{
"generateScopedName": "[name]__[local]___[hash:base64:5]"
}
]
]
}
webpack.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/index.jsx",
mode: "development",
module: {
rules: [
{
enforce: "pre",
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
loader: "eslint-loader",
options: {
fix: true
}
},
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
use: ["babel-loader", "react-hot-loader/webpack"],
},
{
test: /\.css$/,
use: ["style-loader", {loader: "css-loader", options: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}}]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
},
resolve: {
alias: {
'react-dom': '#hot-loader/react-dom'
},
extensions: ["*", ".js", ".jsx"]
},
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "/dist/",
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "public/"),
port: 3000,
publicPath: "http://localhost:3000/dist/",
hotOnly: true
},
plugins: [new webpack.HotModuleReplacementPlugin()]
};
package.json
{
"name": "shopping-page",
"version": "1.0.0",
"description": "Hi!",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server",
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+ssh://git#gitlab.com/mgoldwater-nisum-com/shopping-page.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://gitlab.com/mgoldwater-nisum-com/shopping-page/issues"
},
"homepage": "https://gitlab.com/mgoldwater-nisum-com/shopping-page#README",
"dependencies": {
"#babel/cli": "^7.2.3",
"#babel/core": "^7.2.2",
"#babel/preset-env": "^7.3.1",
"#babel/preset-react": "^7.0.0",
"#hot-loader/react-dom": "^16.8.1",
"babel-jest": "^24.1.0",
"babel-loader": "^8.0.5",
"babel-plugin-react-css-modules": "^5.0.0",
"css-loader": "^2.1.0",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.9.1",
"eslint-loader": "^2.1.2",
"file-loader": "^3.0.1",
"identity-obj-proxy": "^3.0.0",
"jest": "^24.1.0",
"react": "^16.8.1",
"react-dom": "^16.8.1",
"react-hot-loader": "^4.6.5",
"style-loader": "^0.23.1",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.1.14"
},
"devDependencies": {
"eslint": "^5.13.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.12.4"
},
"jest": {
"setupFilesAfterEnv": [
"<rootDir>/src/setupTests.js"
],
"moduleNameMapper": {
"\\.(css|less|sass|scss)$": "identity-obj-proxy"
}
}
}