reactjs - Styled components: babel-plugin-styled-components fungerar inte
Jag har försökt få babel-plugin-styled-components-pluginen att fungera med min webpack/babelrc-konfiguration men jag har inte lyckats. Jag använder babel-loader och oavsett vad jag försöker kan jag inte få pluginen att bli igenkänd.
Jag använder Typescript 4 och Webpack 4.
Jag har sökt och provat ett antal föreslagna lösningar men ingen har fungerat. Jag provade till och med typescript-styled-components-plugin-lösningen (https://github.com/Igorbek/typescript-plugin-styled-components), men oavsett vad verkar det som att pluginet inte känns igen och inställningarna fungerar inte.
Jag kan bara föreställa mig att det är ett problem med min konfiguration. Webpack är fortfarande lite av ett mysterium för mig i allmänhet.
Min webpack.common.js-fil ser ut så här:
module.exports = [
{
context,
cache: local,
devtool: 'inline-source-map',
mode: 'development',
resolve: {
symlinks: false,
alias: {
'app.veams$': `${context}/app.veams.tsx`,
env: envFile
},
extensions: ['.ts', '.tsx', '.js']
},
// Entry point for webpack
entry: {
app: `${context}/app.tsx`
},
// Output directory and filename
output: {
filename: 'scripts/[name].bundle.js',
chunkFilename: 'scripts/[name].chunk.js',
path: outputPath,
pathinfo: !local // Performance #2: Garbage Collection
},
// Tell webpack to run babel on every file it runs through
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
babelrc: true,
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
// Let's add babel presets ...
presets: [
'@babel/preset-react',
[
'@babel/preset-env',
{
targets: {
browsers: ['last 2 versions', 'ie >= 11']
}
}
]
],
// ... and plugins.
plugins: [
'@babel/plugin-proposal-function-bind',
// Stage 2
[
'@babel/plugin-proposal-decorators',
{
legacy: true
}
],
[
'@babel/plugin-proposal-class-properties',
{
loose: false
}
]
]
}
}
]
},
scriptRule(configContext),
styleRule(),
assetsRule()
]
},
plugins: [].concat(scriptPlugins(configContext), stylePlugins(configContext)),
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
},
// Turn off performance hints during development because we don't do any
// splitting or minification in interest of speed. These warnings become
// cumbersome.
performance: {
hints: false
},
optimization: {
minimizer: optimizerPlugins(),
removeAvailableModules: false, // Performance #1: Do not optimize so much in incremental builds
removeEmptyChunks: false, // Performance #1: Do not optimize so much in incremental builds
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
chunks: 'initial',
name: 'vendor',
priority: 10,
enforce: true
}
} // Performance #1: Do not optimize so much in incremental builds
}
},
devServer: {
contentBase: outputPath,
compress: false,
port: 3000,
proxy: {
'/': 'http://localhost:2999'
},
overlay: {
warnings: true,
errors: true
}
}
}
];
Filen scriptRule ser ut så här:
module.exports = function() {
return {
test: /\.tsx?$/,
use: [
{
loader: 'cache-loader'
},
{
loader: 'babel-loader',
options: {
babelrc: true,
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
// Let's add babel presets ...
presets: [
'@babel/preset-react',
[
'@babel/preset-env',
{
targets: {
browsers: ['last 2 versions', 'ie >= 11']
}
}
]
],
// ... and plugins.
plugins: [
'@babel/plugin-proposal-function-bind',
// Stage 2
[
'babel-plugin-styled-components',
{
displayName: true
}
],
[
'@babel/plugin-proposal-decorators',
{
legacy: true
}
],
[
'@babel/plugin-proposal-class-properties',
{
loose: false
}
]
]
}
},
{
loader: 'thread-loader',
options: {
// there should be 1 cpu for the fork-ts-checker-webpack-plugin
workers: require('os').cpus().length - 1
}
},
{
loader: 'ts-loader',
options: {
transpileOnly: true, // Performance #3 :: Limit amount of modules to transpile at a time per iteration
experimentalWatchApi: true,
happyPackMode: true // IMPORTANT! use happyPackMode mode to speed-up compilation and reduce errors
// reported to webpack
}
}
]
};
};
.babelrc ser ut så här:
{
"env": {
"client": {
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": ["last 2 versions", "ie >= 11"]
}
}
],
"@babel-preset-react"
],
"plugins": [
"@babel/plugin-proposal-function-bind",
[
"babel-plugin-styled-components",
{
"displayName": true
}
],
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": false
}
]
]
},
"server": {
"presets": ["@babel/preset-env"],
"plugins": [
"@babel/plugin-proposal-function-bind",
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-proposal-logical-assignment-operators",
[
"@babel/plugin-proposal-optional-chaining",
{
"loose": false
}
],
[
"@babel/plugin-proposal-pipeline-operator",
{
"proposal": "minimal"
}
],
[
"@babel/plugin-proposal-nullish-coalescing-operator",
{
"loose": false
}
],
"@babel/plugin-proposal-do-expressions",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
[
"@babel/plugin-proposal-class-properties",
{
"loose": false
}
],
"@babel/plugin-proposal-json-strings",
"@babel/plugin-transform-runtime"
]
}
}
}
Och slutligen ser package.json ut så här:
"dependencies": {
"@veams/core": "^1.0.0",
"@veams/helpers": "^1.2.8",
"@veams/http-service": "^1.0.2",
"c3": "0.7.20",
"carbon-components": "^9.66.3",
"carbon-components-react": "^6.74.1",
"carbon-icons": "^7.0.7",
"connected-react-router": "6.8.0",
"cors": "2.8.5",
"downshift": "3.1.5",
"express-http-proxy": "1.6.2",
"file-saver": "2.0.2",
"history": "4.7.2",
"html-to-react": "1.4.5",
"immutable": "4.0.0-rc.12",
"json5": "2.1.3",
"query-string": "6.13.7",
"react": "17.0.1",
"react-c3js": "0.1.20",
"react-d3-cloud": "0.7.0",
"react-dom": "17.0.1",
"react-excel-workbook": "0.0.4",
"react-redux": "7.2.2",
"react-router-config": "4.4.0-beta.6",
"react-router-dom": "5.2.0",
"redux": "4.0.5",
"redux-devtools-extension": "2.13.8",
"redux-immutable": "4.0.0",
"redux-immutable-state-invariant": "2.1.0",
"redux-observable": "1.2.0",
"reselect": "4.0.0",
"rxjs": "6.6.3",
"styled-components": "5.2.1",
"tslib": "2.0.3",
"xlsx": "0.16.8"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/register": "^7.0.0",
"@babel/runtime": "^7.0.0",
"@types/history": "^4.6.2",
"@types/jest": "^23.3.12",
"@types/node": "^10.12.18",
"@types/react": "16.9.56",
"@types/react-dom": "16.9.9",
"@types/react-redux": "7.1.11",
"@types/react-router": "4.4.3",
"@types/react-router-config": "1.0.7",
"@types/react-router-dom": "5.1.6",
"@types/redux-immutable-state-invariant": "2.1.1",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.4.2",
"babel-loader": "^8.0.5",
"babel-plugin-styled-components": "1.11.1",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.16.0",
"babel-preset-stage-1": "^6.24.1",
"babel-register": "^6.26.0",
"babel-runtime": "^6.26.0",
"body-parser": "^1.18.1",
"browser-sync": "^2.24.4",
"cache-loader": "^2.0.1",
"case-sensitive-paths-webpack-plugin": "^2.1.1",
"chalk": "^2.0.1",
"command-line-args": "^4.0.7",
"command-line-usage": "^4.0.2",
"compression-webpack-plugin": "^2.0.0",
"connect-browser-sync": "^2.1.0",
"copy-webpack-plugin": "^4.3.1",
"cross-env": "^5.0.5",
"css-loader": "^2.1.0",
"deep-extend": "^0.6.0",
"eslint": "^5.12.0",
"eslint-config-prettier": "^3.4.0",
"eslint-plugin-prettier": "^3.0.1",
"express": "^4.16.3",
"fork-ts-checker-webpack-plugin": "^0.5.2",
"globby": "^9.0.0",
"husky": "^1.0.0-rc.8",
"include-media": "^1.4.8",
"jshint-stylish": "^2.0.0",
"lint-staged": "^8.1.5",
"lodash": "^4.17.4",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.7.2",
"node-sass-magic-importer": "^5.0.3",
"nodemon": "^1.14.0",
"npm-run-all": "^4.1.1",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss": "^7.0.11",
"postcss-cssnext": "^3.1.0",
"postcss-loader": "^3.0.0",
"prettier": "^1.13.4",
"react-dev-utils": "^7.0.1",
"request": "^2.81.0",
"rimraf": "^2.6.2",
"sass-loader": "^7.0.2",
"style-loader": "^0.23.1",
"stylelint": "^9.2.0",
"stylelint-config-prettier": "^5.0.0",
"stylelint-prettier": "^1.0.6",
"thread-loader": "^2.1.1",
"ts-jest": "^23.10.5",
"ts-loader": "^5.3.3",
"tslint": "^5.12.0",
"tslint-config-airbnb": "^5.9.2",
"tslint-config-prettier": "^1.13.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-react": "^3.6.0",
"typescript": "4.0.5",
"uglifyjs-webpack-plugin": "^2.1.1",
"webpack": "^4.10.2",
"webpack-cli": "^3.0.1",
"webpack-dev-server": "^3.1.14",
"winston": "^2.3.1"
},
Jag skrev inte ursprungligen denna webpack-konfiguration och har försökt ändra ordningen på pluginet osv. utan framgång.
Jag hoppas att någon kan hjälpa...
Skål!
Svar #1
Det verkar som att du kanske behöver lägga till "babel-plugin-macros" innan det i din plugins-array. Jag surfade på webben i evigheter och försökte få babel-plugin-styled-components att fungera för Twin i Create React App (som också använder Webpack). Jag använde CRACO för att lägga till babel-plugins, men inget jag gjorde fungerade.
Jag råkade slutligen på detta helt perfekta exempelrepo twin.examples/webpack-styled-components-typescript som innehöll bokstavligen allt jag ville ha. Här är .babelrc-filen det använde:
{
"presets": [
[
"@babel/preset-react",
{ "runtime": "automatic" }
],
"@babel/preset-typescript"
],
"plugins": [
"babel-plugin-twin",
"babel-plugin-macros",
"babel-plugin-styled-components"
]
}
Plugins-delen var det jag behövde, så jag kopierade bara över den och allt fungerade perfekt.
För att kontrollera att det tillämpades på situationer utan babel-plugin-twin tog jag bort det från pluginslistan och testade min setup med den alternativa metoden för att använda Twin (genom att lägga till import "twin.macro" högst upp i filen jag stylade i). Setupen fungerade, men inte om jag tog bort babel-plugins-macro, vilket stöder min teori.
Vad som verkar konstigt är att CRA redan laddar babel-plugins-macro från babel-preset-react-app. Jag tror faktiskt att babel-plugins-macro behöver laddas specifikt precis före babel-plugin-styled-components, eftersom jag försökte byta plats på just de två och det tyst förstörde stylingen.
Hoppas att mina fynd hjälper dig eller någon annan där ute!
