reactjs - Styled components: babel-plugin-styled-components fungerer ikke
Jeg har forsøkt å få babel-plugin-styled-components-pluginen til å fungere med min webpack/babelrc-konfigurasjon, men jeg har ikke klart å gjøre det. Jeg bruker babel-loader, og uansett hva jeg prøver, klarer jeg ikke å få pluginen til å bli gjenkjent.
Jeg bruker Typescript 4 og Webpack 4.
Jeg har søkt og prøvd en rekke foreslåtte løsninger, men ingen har fungert. Jeg prøvde til og med typescript-styled-components-plugin-løsningen (https://github.com/Igorbek/typescript-plugin-styled-components), men uansett ser det ut til at pluginen ikke blir gjenkjent og innstillingene fungerer ikke.
Jeg kan bare forestille meg at det er et problem med konfigurasjonen min. Webpack er fortsatt litt av et mysterium for meg generelt.
Min webpack.common.js-fil ser slik ut:
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 slik ut:
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 slik ut:
{
"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"
]
}
}
}
Og til slutt ser package.json slik ut:
"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"
},
Jeg skrev opprinnelig ikke denne webpack-konfigurasjonen og har prøvd å endre rekkefølgen på plugin-en osv. uten hell.
Jeg håper noen kan hjelpe...
Skål!
Svar #1
Det ser ut til at du kanskje må legge til "babel-plugin-macros" før det i plugins-arrayen din. Jeg søkte på nettet i evigheter for å få babel-plugin-styled-components til å fungere for Twin i Create React App (som også bruker Webpack). Jeg brukte CRACO for å legge til babel-plugins, men ingenting jeg gjorde fungerte.
Jeg snublet endelig over dette helt perfekte eksempel-repoet twin.examples/webpack-styled-components-typescript som inneholdt bokstavelig talt alt jeg ønsket. Her er .babelrc-filen den brukte:
{
"presets": [
[
"@babel/preset-react",
{ "runtime": "automatic" }
],
"@babel/preset-typescript"
],
"plugins": [
"babel-plugin-twin",
"babel-plugin-macros",
"babel-plugin-styled-components"
]
}
Plugins-delen var det jeg trengte, så jeg kopierte den bare over, og alt fungerte perfekt.
For å sjekke at det ble brukt i situasjoner uten babel-plugin-twin, fjernet jeg det fra plugins-listen og testet oppsettet mitt ved å bruke den alternative metoden for å bruke Twin (ved å legge til import "twin.macro" øverst i filen jeg stylet i). Oppsettet fungerte, men ikke hvis jeg fjernet babel-plugins-macro, noe som støttet teorien min.
Det som virker merkelig er at CRA allerede laster babel-plugins-macro fra babel-preset-react-app. Jeg tror faktisk at babel-plugins-macro må lastes spesifikt rett før babel-plugin-styled-components, ettersom jeg prøvde å bytte rekkefølgen på bare de to, og det ødela stilen stille og rolig.
Håper funnene mine hjelper deg eller noen andre der ute!
