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
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.
I am creating a npm package with react components, providers, and other utilities. The idea is use this npm package in other projects. I configured rollup to create the builds but when I try to use it in another project I got a "React is not defined" error.
Here is my code and the error in detail:
package.json:
{
"name": "myapp",
"version": "0.1.14",
"description": "Npm package.",
"main": "lib/index.cjs.js",
"module": "lib/index.esm.js",
"files": [
"dist",
"README.md"
],
"scripts": {
"start": "react-scripts start",
"build": "npx rollup -c",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": ""
},
"author": "",
"license": "ISC",
"dependencies": {
"#babel/polyfill": "^7.12.1",
"#fluentui/react": "8.52.2",
"#rjsf/core": "4.2.0",
"#rjsf/fluent-ui": "4.2.0",
"#types/node": "^17.0.21",
"#types/react": "^17.0.40",
"#types/react-dom": "^17.0.13",
"axios": "^0.25.0",
"office-ui-fabric-core": "^11.0.0",
"react-query": "^3.34.19",
"react-simple-resizer": "^2.1.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0",
"#fluentui/react": "8.52.2"
},
"devDependencies": {
"#babel/cli": "^7.17.0",
"#babel/core": "^7.17.0",
"#babel/preset-env": "^7.16.11",
"#babel/preset-react": "^7.16.7",
"#fluentui/example-data": "^8.4.0",
"#rollup/plugin-babel": "^5.3.0",
"#rollup/plugin-commonjs": "^21.0.1",
"#rollup/plugin-node-resolve": "^13.1.3",
"#rollup/plugin-replace": "^4.0.0",
"#rollup/plugin-typescript": "^8.3.1",
"react-scripts": "^5.0.0",
"rollup": "^2.67.1",
"rollup-plugin-import-css": "^3.0.3",
"rollup-plugin-includepaths": "^0.2.4",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-terser": "^7.0.2",
"typescript": "^4.6.2",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
rollup.config.js:
import babel from "#rollup/plugin-babel";
import resolve from "#rollup/plugin-node-resolve";
import commonjs from "#rollup/plugin-commonjs";
import includePaths from "rollup-plugin-includepaths";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import { terser } from "rollup-plugin-terser";
import pkg from "./package.json";
import typescript from "#rollup/plugin-typescript";
import css from "rollup-plugin-import-css";
import replace from "#rollup/plugin-replace";
const outputs = [
{
file: pkg.main,
format: "umd",
},
{
file: pkg.module,
format: "es",
}
]
const external = [
...Object.keys(pkg.peerDependencies || {})
].map(name => RegExp(`^${name}($|/)`))
const config = outputs.map(({ file, format }) => ({
input: "src/lib/index.js",
output: {
file,
format,
name: "ReactPackage",
globals: {
react: "React",
"react-dom": "ReactDOM",
"#fluentui/react": "FluentUI",
}
},
external,
plugins: [
typescript(),
peerDepsExternal(),
includePaths({
include: {},
paths: ["src/lib"],
external: Object.keys(pkg.dependencies),
extensions: ['.js', '.json', '.html', '.tsx', '.ts']
}),
css(),
babel({
babelHelpers: "bundled",
exclude: "node_modules/**",
configFile: "./babel.config.rollup.js",
}),
resolve({
browser: true
}),
commonjs(),
terser(),
replace({
preventAssignment: true,
'process.env.NODE_ENV': JSON.stringify('production')
})
],
}));
export default config;
Babel:
const pkg = require('./package.json');
module.exports = {
presets: [
[
'#babel/preset-env',
{
modules: false,
targets: pkg.browserslist.production,
},
],
[
'#babel/preset-react',
{
"runtime": "automatic"
}
]
],
ignore: ['node_modules/**'],
};
The provider that I am trying to use but I get an "React is not defined" error:
Provider.ts:
import PContext from "../contexts/pContext";
import { QueryClient, QueryClientProvider } from "react-query";
import React, { useState } from "react";
const queryClient = new QueryClient();
const PProvider = ({ children, url }) => {
const [active, setActive] = useState(null);
return (
<PContext.Provider
value={{
url,
active,
setActive
}}
>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</PContext.Provider>
);
};
export default PProvider;
I'm having a hard time to get Relay working within my monorepo. I have set everything up with Yarn workspaces (version berry) and Webpack 5.
When I'm trying to run one of my apps, I get the error:
MacroError: The macro you imported from "undefined" is being executed outside the context of
compilation with babel-plugin-macros. This indicates that you don't have the babel plugin
"babel-plugin-macros" configured correctly. Please see the documentation for how to configure
babel-plugin-macros properly:
https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/user.md
I also get 2 warnings:
Compiled with problems:
WARNING in ../../../.yarn/cache/babel-plugin-macros-npm-2.8.0-451367d7e7-59b09a21cf.zip/node_modules/babel-plugin-macros/dist/index.js 78:24-31
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ../../../.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip/node_modules/import-fresh/index.js 32:31-48
Critical dependency: the request of a dependency is an expression
I have already checked the sources of both, the babel-plugin-marcos and the babel-plugin-relay package and I could locate the lines of error (read here for further information) but I can't figure out what is going on.
My setup
package.json
{
"name": "#apps/app1",
"version": "0.0.1",
"private": true,
"packageManager": "yarn#3.2.0",
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"dependencies": {
"#chakra-ui/react": "^1.8.8",
"#emotion/react": "^11.9.0",
"#emotion/styled": "^11.8.1",
"framer-motion": "^6.2.10",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-relay": "^13.2.0"
},
"devDependencies": {
"#babel/core": "^7.17.9",
"#babel/plugin-transform-runtime": "^7.17.0",
"#babel/preset-env": "^7.16.11",
"#babel/preset-react": "^7.16.7",
"#babel/preset-typescript": "^7.16.7",
"#babel/runtime": "^7.17.9",
"#types/babel__core": "^7",
"#types/babel__plugin-transform-runtime": "^7",
"#types/babel__preset-env": "^7",
"#types/events": "^3",
"#types/node": "^17.0.24",
"#types/react": "^18.0.3",
"#types/react-dom": "^18.0.0",
"#types/react-relay": "^13.0.2",
"#types/yup": "^0.29.13",
"babel-loader": "^8.2.4",
"babel-plugin-relay": "^13.2.0",
"buffer": "^6.0.3",
"crypto-browserify": "^3.12.0",
"events": "^3.3.0",
"graphql": "^16.3.0",
"html-webpack-plugin": "^5.5.0",
"http-proxy-middleware": "^2.0.4",
"module": "^1.2.5",
"os-browserify": "^0.3.0",
"path-browserify": "^1.0.1",
"pnp-webpack-plugin": "^1.7.0",
"process": "^0.11.10",
"stream-browserify": "^3.0.0",
"string_decoder": "^1.3.0",
"ts-node": "^10.7.0",
"typescript": "^4.6.3",
"util": "^0.12.4",
"web-vitals": "^2.1.4",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.8.1"
},
"scripts": {
"start": "webpack serve --config webpack.dev.config.ts --stats-error-details"
}
}
webpack.dev.config.ts
import * as path from "path";
import { Configuration as WebpackConfiguration, ProvidePlugin } from "webpack";
import { Configuration as WebpackDevServerConfiguration } from "webpack-dev-server";
const HtmlWebpackPlugin = require("html-webpack-plugin");
const PnpWebpackPlugin = require("pnp-webpack-plugin");
interface Configuration extends WebpackConfiguration {
devServer?: WebpackDevServerConfiguration;
}
const config: Configuration = {
mode: "development",
output: {
publicPath: "/",
},
entry: path.resolve(__dirname, "src/index.tsx"),
resolve: {
plugins: [PnpWebpackPlugin],
extensions: [".tsx", ".ts", ".js", "jsx"],
fallback: {
path: require.resolve("path-browserify"),
stream: require.resolve("stream-browserify"),
util: require.resolve("util/"),
crypto: require.resolve("crypto-browserify"),
buffer: require.resolve("buffer/"),
events: require.resolve("events/"),
string_decoder: require.resolve("string_decoder/"),
os: require.resolve("os-browserify/browser"),
fs: false,
module: false
},
},
resolveLoader: {
plugins: [PnpWebpackPlugin.moduleLoader(module)],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "public/index.html"),
}),
new ProvidePlugin({ process: "process/browser.js" }),
],
module: {
rules: [
// { test: /\.(css)$/, use: ["style-loader", "css-loader"] },
{ test: /\.(svg|ico|png|gif|jpg|jpeg)$/, type: "asset/ressource" },
{
test: /\.(ts|tsx)?$/i,
// exclude: /node_modules/,
use: {
loader: require.resolve("babel-loader"),
options: {
generatorOpts: { compact: false },
presets: [
"#babel/preset-env",
["#babel/preset-react", { runtime: "automatic" }],
"#babel/preset-typescript",
],
},
},
},
],
},
devtool: "inline-source-map",
devServer: {
static: path.join(__dirname, "public"),
historyApiFallback: true,
port: 4000,
open: true,
hot: true,
},
};
export default config;
babel.rc
{
"presets": ["#babel/preset-env", ["#babel/preset-react", { "runtime": "automatic" }], "#babel/preset-typescript"],
"plugins": [
["relay", { "artifactDirectory": "../../__generated__", "eagerESModules": true }],
["#babel/plugin-transform-runtime", { "regenerator": true }]
]
}
Any tips welcome!
Alright, I've got rid of the error by
deleting the .babelrc file(s)
deleting the babel-plugin-macros.config.js file(s)
adding the Relay plugin configuration to the webpack.config.dev.ts
The relevant part of my webpack.config looks like this now
module: {
rules: [
{
test: /\.(ts|tsx)?$/,
use: {
loader: require.resolve("babel-loader"),
options: {
generatorOpts: { compact: false },
presets: [
"#babel/preset-env",
["#babel/preset-react", { runtime: "automatic" }],
"#babel/preset-typescript",
],
plugins: [
["relay", { artifactDirectory: "../../__generated__", eagerESModules: true }],
["#babel/plugin-transform-runtime"],
],
},
},
},
],
},
However, the two warnings still persist!
Compiled with problems:
WARNING in ../../../.yarn/cache/babel-plugin-macros-npm-2.8.0-451367d7e7-59b09a21cf.zip/node_modules/babel-plugin-macros/dist/index.js 78:24-31
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ../../../.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip/node_modules/import-fresh/index.js 32:31-48
Critical dependency: the request of a dependency is an expression
I have read that it might have to do with some asynchronous call of a macro!? Can I safely ignore these warnings? Is this a webpack issue?
Update ---
I have submitted an issue report at the Webpack GitHub Repo and according to them the babel-plugin-macros warning
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
is a result of something like
importSomeModules(require);
// or
const myRequire = require;
where require is not a call expression (eg: require(), require.resolve()).
In case of babel-plugin-macros this is
function macrosPlugin(babel,
// istanbul doesn't like the default of an object for the plugin options
// but I think older versions of babel didn't always pass options
// istanbul ignore next
{
require: _require = require,
resolvePath = nodeResolvePath,
isMacrosName = testMacrosRegex,
...options
} = {}) {}
Unfortunately, babel-plugin-macros is not being maintained anymore (though still a dependency for babel-plugin-relay).
The other warning coming from import-fresh
Critical dependency: the request of a dependency is an expression
is a result of something like
let var1 = someCall();
require(var1); // webpack can't determine var1 value
Guess the affected line of the package can be found here.
I've created a Typescript, React project that makes use of Storybook.js, that contains all of my components, styling and images for the project I'm working on.
I package this project with the help of Webpack and then via an Azure pipeline I build and publish it to a private feed. I then install the package(npm install) with no problems on my main project, which is a Typescript, Next.js project. When I try to import the package into a page,
import {Footer} from '#private_feed/generic.project/dist/bundle.js'
I get the error mentioned in the title, along with:
./node_modules/next/dist/next-server/server/require.js
Critical dependency: the request of a dependency is an expression
./node_modules/next/dist/next-server/server/load-components.js
Critical dependency: the request of a dependency is an expression
> Build error occurred
ReferenceError: document is not defined
I had it working before when i had no css and no images. I was compiling down my Typescript with tsc and all my styling was making use of styled-components. However, for project and team related reasons I need to be able to make use of css files and unfortunately not use styled-components.
The following files belong to the project that is being packaged.
package.json
{
"name": "#private_feed/generic.project",
"version": "0.1.11",
"files": [
"dist"
],
"dependencies": {
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.2.1",
"#types/jest": "^24.9.1",
"#types/node": "^12.12.47",
"#types/react": "^16.9.41",
"#types/react-dom": "^16.9.8",
"#types/styled-components": "^5.1.0",
"cross-env": "^7.0.2",
"lodash": "^4.17.15",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"styled-components": "^5.1.1"
},
"scripts": {
"start": "react-scripts start",
"test": "react-scripts test",
"eject": "react-scripts eject",
"storybook": "start-storybook -p 9009 -s public",
"build-storybook": "build-storybook -s public",
"build": "webpack"
},
"eslintConfig": {
"extends": "react-app"
},
"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": "^5.3.19",
"#storybook/addon-knobs": "^5.3.19",
"#storybook/addon-links": "^5.3.19",
"#storybook/addons": "^5.3.19",
"#storybook/preset-create-react-app": "^3.1.2",
"#storybook/react": "^5.3.19",
"#types/lodash": "^4.14.157",
"css-loader": "^3.6.0",
"file-loader": "^6.0.0",
"style-loader": "^1.2.1",
"ts-loader": "^7.0.5",
"typescript": "^3.9.6",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12"
},
"babel": {
"presets": [
"react-app"
]
},
"description": "This project was bootstrapped with [Create React App].",
"author": "",
"license": "ISC"
}
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.ts',
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg)$/,
use: [
'file-loader',
],
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
tsconfig.json
{
"compilerOptions": {
"outDir": "dist",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"es2015"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react",
"noImplicitAny": true,
"sourceMap": true,
"typeRoots": ["./src/#types", "./node_modules/#types"]
},
"include": [
"src", "types"
]
}
src/#types/assets/index.d.ts
declare module "\*.svg" {
import React = require("react");
export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
declare module "\*.css" {
const content: string;
export default content;
}
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'
]
}
}
};