Typescript
React
SCSS
のアーキテクチャで検証をしているところで、babel-plugin-react-css-modules
という便利そうなプラグインの導入を試してみたのですが、うまくいかなくて困っております。
どのようなプラグインかは、ざっと下記の通りです。
従来のcss modules
javascript
1import style from "sample.scss"; 2 3export default class Sample extends React.Component<Props, States> { 4 render() { 5 return ( 6 <div className={style["sample__color"]}> 7 } 8 } 9}
プラグインを使ったcss modules
javascript
1import "sample.scss"; 2 3export default class Sample extends React.Component<Props, States> { 4 render() { 5 return ( 6 <div styleName="sample__color"> 7 } 8 } 9}
自然な形でstyleを適用できるため、できるならこれを組み込みたいと思っておりますが、このプラグインを使って、特定のstyleが適用されない下記のエラーが発生しました。
このときのコードは下記の通りです。
javascript
1class Icon extends React.Component<Props, States> { 2 static defaultProps = { 3 iconSize: IconSize.SMALL, 4 iconColor: IconColor.MARINE, 5 } 6 7 constructor(props: Props) { 8 super(props); 9 this.state = {}; 10 } 11 12 render() { 13 const { iconSize, iconColor, iconType } = this.props; 14 return ( 15 <span styleName={classNames({ 16 "icon": true, 17 [iconSize]: true, 18 [iconColor]: true, 19 [iconType]: true, 20 })} /> 21 ); 22 } 23}
いろいろ原因を探っていくと、ビルドされたindex.jsでicon-size__small
と記述したはずがicon-size
と間違ってコンパイルされてしまっている箇所を確認しました。
この後icon-size__small
をicon-size-small
など、別の表記に変えてみたのですが、変わらずicon-size__small
とコンパイルされてしまい詰んでいます。
この後の処理として、プラグインのgetClassNameメソッド
内部で、引数で渡されたvar_styleModuleImportMap
からicon-size__small
を取得しようとしているため、エラーが発生しているように思われます。
これはプラグインのバクでしょうか?もしくは私のwebpackの設定がおかしいのでしょうか?
var _styleModuleImportMap = { // おかしなコンパイルがされている箇所 './style.scss': { 'icon': '_8v9KQQGXtFBbuivuMsbiP', 'icon-size': '_3DPAfBHWjIT2YORKHVi658', 'icon-type': 'plX81wh4YqJi52fDFHH2u', 'icon-color': '_2pELW_Pbop5E3WYZz1jCZv' } }; __WEBPACK_IMPORTED_MODULE_2_react_dom__["render"](__WEBPACK_IMPORTED_MODULE_1_react__["createElement"]( 'div', { className: '_37bpL3h0MVIiXuX_UECkaH' }, __WEBPACK_IMPORTED_MODULE_1_react__["createElement"]('span', { className: __WEBPACK_IMPORTED_MODULE_0_babel_plugin_react_css_modules_dist_browser_getClassName___default()(__WEBPACK_IMPORTED_MODULE_3_classnames___default()({ "icon": true, "icon-size__small": true, "icon-type__balloon": true, "icon-color__marine": true }), _styleModuleImportMap) }) ), document.getElementById('app'));
下記は各種設定ファイルになります。
このプラグインについてお詳しい方がいらっしゃれば、アドバイス頂けないでしょうか?
package.json
json
1"dependencies": { 2 "babel-polyfill": "6.26.0", 3 "classnames": "2.2.6", 4 "react": "16.6.0", 5 "react-dom": "16.6.0", 6 "react-router": "4.3.1", 7 "react-router-dom": "4.3.1", 8 "recompose": "0.30.0", 9 }, 10 "devDependencies": { 11 "@types/classnames": "2.2.6", 12 "@types/react": "16.4.14", 13 "@types/react-css-modules": "4.6.2", 14 "@types/react-dom": "16.0.8", 15 "@types/react-redux": "6.0.9", 16 "@types/react-router-dom": "4.3.1", 17 "@types/react-router-redux": "5.0.16", 18 "autoprefixer": "9.3.1", 19 "babel-loader": "7.1.2", 20 "babel-plugin-react-css-modules": "3.4.2", 21 "babel-plugin-transform-react-jsx": "6.24.1", 22 "babel-preset-env": "1.7.0", 23 "babel-preset-react": "6.24.1", 24 "css-loader": "1.0.1", 25 "file-loader": "2.0.0", 26 "html-webpack-plugin": "3.2.0", 27 "mini-css-extract-plugin": "0.4.4", 28 "node-sass": "4.9.4", 29 "postcss-loader": "3.0.0", 30 "postcss-scss": "2.0.0", 31 "react-css-modules": "4.7.7", 32 "sass-loader": "7.1.0", 33 "style-loader": "0.23.1", 34 "ts-loader": "5.2.1", 35 "typescript": "3.1.1", 36 "uglifyjs-webpack-plugin": "2.0.1", 37 "webpack": "4.23.1", 38 "webpack-cli": "3.1.2", 39 "webpack-dev-server": "3.1.10" 40 }
webpack.config.js
javascript
1const path = require('path'); 2const webpack = require('webpack'); 3const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 4const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 5const HtmlWebpackPlugin = require('html-webpack-plugin'); 6 7const SOURCE_DIRECTORY = path.resolve(__dirname, 'resources'); 8const OUTPUT_DIRECTORY = path.resolve(__dirname, 'build'); 9const MODULE_DIRECTORY = path.resolve(__dirname, 'node_modules'); 10 11module.exports = (env, argv) => { 12 const __DEV__ = argv.mode === 'development'; 13 return ({ 14 context: SOURCE_DIRECTORY, 15 entry: [ 16 'babel-polyfill', 17 './index.tsx' 18 ], 19 output: { 20 filename: 'index.js', 21 path: OUTPUT_DIRECTORY, 22 publicPath: '/' 23 }, 24 module: { 25 rules: [ 26 { 27 include: SOURCE_DIRECTORY, 28 test: /.(ts|tsx)$/, 29 use: [ 30 { 31 loader: 'babel-loader', 32 options: { 33 cacheDirectory: __DEV__ 34 } 35 }, 36 'ts-loader' 37 ] 38 }, 39 { 40 include: SOURCE_DIRECTORY, 41 test: /.scss$/, 42 use: [ 43 MiniCssExtractPlugin.loader, 44 { 45 loader: 'css-loader', 46 options: { 47 modules: true, 48 minimize: !__DEV__, 49 sourceMap: __DEV__, 50 localIdentName: __DEV__ ? '[hash:base64:5]' : null, 51 url: false 52 } 53 }, 54 { 55 loader: 'sass-loader', 56 options: { 57 sourceMap: __DEV__ 58 } 59 }, 60 { 61 loader: 'postcss-loader', 62 options: { 63 sourceMap: __DEV__ 64 } 65 } 66 ] 67 } 68 ] 69 }, 70 resolve: { 71 extensions: ['.tsx', '.ts', '.js'], 72 }, 73 devServer: { 74 host: 'localhost', 75 port: 8082, 76 compress: true, 77 contentBase: __dirname, 78 historyApiFallback: true, 79 hot: true 80 }, 81 plugins: [ 82 new webpack.HotModuleReplacementPlugin(), 83 new webpack.NamedModulesPlugin(), 84 new webpack.NoEmitOnErrorsPlugin(), 85 new webpack.DefinePlugin({ 86 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) 87 }), 88 new HtmlWebpackPlugin({ 89 template: 'index.html', 90 filename: 'index.html' 91 }), 92 new MiniCssExtractPlugin({ 93 filename: 'index.css' 94 }), 95 ...(__DEV__ ? [] : [new UglifyJsPlugin()]) 96 ], 97 cache: false 98 }); 99};
.babelrc
json
1{ 2 "presets": [ 3 [ 4 "env", 5 { 6 "targets": { 7 "browsers": [ 8 "IE >= 11", 9 "Edge >= 16", 10 "Chrome >= 64", 11 "Firefox >= 58", 12 "Safari >= 11" 13 ] 14 }, 15 "modules": false 16 } 17 ], 18 "react" 19 ], 20 "plugins": [ 21 "transform-react-jsx", 22 [ 23 "react-css-modules", 24 { 25 "context": "resources", 26 "filetypes": { 27 ".scss": { 28 "syntax": "postcss-scss" 29 } 30 }, 31 "handleMissingStyleName": "warn", 32 "generateScopedName": "[hash:base64]" 33 } 34 ] 35 ] 36}
あなたの回答
tips
プレビュー