React Styleguidist and SASS - reactjs

So my set up is pretty simple
styleguide.config.js
module.exports = {
components: 'src/components/**/*.js',
require: [
path.join(__dirname, 'node_modules/bootstrap/scss/bootstrap.scss')
]
};
Whenever I run npm run styleguide I get this error:
Module parse failed: Unexpected character # You may need an appropriate loader to handle this file type.
bootstrap.scss looks like this:
#import "node_modules/bootstrap/scss/functions";
#import "node_modules/bootstrap/scss/mixins";
...
...
I understand I need to add SASS-loader but the examples I found are using different context so I cant really figure them out yet.
p.s. SASS works outside React Styleguide when I run the app itself, not styleguide.

Ok so the solution is to make sure that your main project can comiple SASS. But thats a different question.
I just had to add webpackConfig to
styleguide.config.js
module.exports = {
components: 'src/kitchensink/**/*.js',
webpackConfig: require('./config/webpack.config.dev.js'),
require: [
path.join(__dirname, './src/sass/bootstrap.scss')
]
};

Related

Create-react-app + TypeScript + CSS Modules: Auto-generating type definitions without ejecting from CRA

Problem
create-react-app v2+ supports TypeScript and CSS Modules out of the box... separately. The problem arises when you try to use the two together. Facebook had an extensive discussion about this issue and ultimately closed it off on GitHub. So developers have to use hacks and other workarounds to get these two technologies to play nicely together alongside CRA.
Existing workaround:
You can manually create ComponentName.module.css.d.ts files with type definitions like this: export const identifierName: string. This allows you to take advantage of TypeScript's typing and VS Code's auto-complete when you go to import ComponentName.module.css. Unfortunately, this is extremely tedious.
Solution (?):
The folks over at Dropbox created typed-css-modules-webpack-plugin to address this issue; it auto-genertes those *.d.ts files for you. They show how to install it with yarn or npm and then give this minimal code example:
const path = require('path');
const {TypedCssModulesPlugin} = require('typed-css-modules-webpack-plugin');
module.exports = {
entry: './src/index.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
},
{
test: /\.css$/,
use: [
'style-loader',
// Use CSS Modules
{
loader: 'css-loader',
options: {
modules: true,
},
},
],
},
],
},
// Generate typing declarations for all CSS files under `src/` directory.
plugins: [
new TypedCssModulesPlugin({
globPattern: 'src/**/*.css',
}),
],
};
Unfortunately, it's not immediately clear how I can use this with create-react-app. I'm not very knowledgeable when it comes to Webpack, and I'm using customize-cra to avoid ejecting out of create-react-app so I can customize the Webpack configs for some things I need. For example, Ant Design lets you import components on demand by using babel-plugin-import as detailed here:
https://ant.design/docs/react/use-in-typescript#Use-babel-plugin-import
Question: How can I convert the above Webpack configuration code to a customize-cra equivalent so that I don't have to eject out of CRA?
Okay, so I eventually did figure this out, and I wrote a blog post on the subject for anyone who runs into a similar issue:
https://aleksandrhovhannisyan.github.io/blog/dev/how-to-set-up-react-typescript-ant-design-less-css-modules-and-eslint/#3-create-react-app-css-modules-and-typescript-
The solution uses the typescript-plugin-css-modules plugin. Here are the relevant bits from my blog post:
yarn add -D typescript-plugin-css-modules
After it’s installed, add the plugin to your tsconfig.json:
{
"compilerOptions": {
"plugins": [{ "name": "typescript-plugin-css-modules" }]
}
}
Next, create a file named global.d.ts under your src directory. You don’t have to name it global, by the way; you can name the file whatever you want, as long as it has the .d.ts extension. Enter these contents:
declare module '*.module.less' {
const classes: { [key: string]: string };
export default classes;
}
If you want to also use SASS or CSS, simply add more module declarations and change the .less extension.
We’re almost done! Per the plugin’s usage instructions, if you want intellisense to work in VS Code, you’ll need to force VS Code to use your workspace version of TypeScript instead of the globally installed version. Remember when we installed TypeScript via CRA at the very beginning? That’s our workspace version of TypeScript.
Here’s how to use the workspace version of TypeScript in VS Code:
Open any TypeScript file.
Click the version number on the blue status bar at the bottom of VS Code.
Select Use Workspace Version (3.7.3 as of this writing).
Here’s a screenshot to make that clearer:
Once you do that, VS Code will create a .vscode directory in your project for workspace settings.
At this point, you're all set to use CSS Modules with TypeScript.
UPDATE 2022
Note: If you're using react-scripts#2.1.x or higher you don't need to use custom definitions like
declare module '*.module.less' {
const classes: { [key: string]: string };
export default classes;
}
Custom definitions
Note: Create React App users can skip this section if you're using react-scripts#2.1.x or higher.
Also you can add this VS code setting to you local JSON settings file:
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
This will ensure that VS Code will use the project’s version of Typescript instead of the VS Code version and will prompt you to do so if you aren’t already.
Well, everything is correct as said AlexH.
1 in tsconfig.ts.
{
"compilerOptions": {
"plugins": [{ "name": "typescript-plugin-css-modules" }]
}
}
2 in global.d.ts
declare module '*.module.less' {
const classes: { [key: string]: string };
export default classes;
}
But Also in tsconfig you should write
"include": [
"global.d.ts",
...
]

How to configure the webpack configurations in create-react-app

I have a question or problem.
I'm using React v.16 so when I create a project I did with create-react-app that webpack is already preconfigured. And I want work with ol-cesium, and in npmjs I see that I have to:
create an alias to the goog directory. With webpack:
resolve: {
alias: {
'goog': path_to_goog,
}
}
If I dont create a webpack file show me this error:
./node_modules/olcs/AbstractSynchronizer.js
107:22-35 "export 'getUid' (imported as 'olBase') was not found in 'ol/index.js'
How can solve it??? And what is path_to_goog???
EDIT
Thanks to Shishir Anshuman for your help.
Now I add alias on webpack.config.dev.js and webpack.config.prod.js but some me a lot errors.
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
modules: ['node_modules', paths.appNodeModules].concat(
// It is guaranteed to exist because we tweak it in `env.js`
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Ol-Cesium
'goog': '../node_modules/olcs/goog',
},
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
In console show me this error:
./node_modules/olcs/AbstractSynchronizer.js
107:22-35 "export 'getUid' (imported as 'olBase') was not found in 'ol/index.js'
__stack_frame_overlay_proxy_console__ # index.js:2178
handleErrors # webpackHotDevClient.js:178
./node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage # webpackHotDevClient.js:211
./node_modules/sockjs-client/lib/event/eventtarget.js.EventTarget.dispatchEvent # eventtarget.js:51
(anonymous) # main.js:274
./node_modules/sockjs-client/lib/main.js.SockJS._transportMessage # main.js:272
./node_modules/sockjs-client/lib/event/emitter.js.EventEmitter.emit # emitter.js:50
WebSocketTransport.ws.onmessage
In the Codesandbox provided by you, I was unable to find the root cause, but I noticed the following:
I noticed that you have used the ES6 import statement:import OLCesium from "olcs/OLCesium";.
But as per this issue, the module is not yet ported to ES6.
I have never used this library before, So it's hard to figure out what exactly is going on.
Did you try installing https://www.npmjs.com/package/geom ? Since the error says 4.6.4/geom/Point.js is missing.

How can I create a configuration file for react and prevent webpack bundling it?

I added a config.json to application.
in webpack.config.js I defined Config
externals: {
'Config': JSON.stringify(production ? require('./config.prod.json') : require('./config.dev.json'))
},
in application I required config and used it
var Config = require('Config');
However, webpack bundles my config file into index.js(my webpack output file) and I dont want this.
I want to keep my config.json seperate from index.js To achieve this, I excluded my config.json but it did not work.
exclude: [/node_modules/, path.resolve(__dirname, 'config.dev.json'), path.resolve(__dirname, 'config.prod.json')]
Can you please help me if I miss something.
Thanks
As descibed by #thedude you can use webpack's code splitting feature.
Instead of simply doing import config from 'config.json' you can use a really cool feature of code splitting.
require.ensure([], function(require) {
let _config = require("config.json");
this.setState({
_configData: _config
});
});
and when you want to use data of config, do that by checking state
if(this.state._configData) { // this checks _configData is not undefined as well
// use the data of config json
}
When you will compile your code using webpack then two bundle files will be created i.e. bundle.js and 0.bundle.js. This 0.bundle.js has your code of config.json file.
You should use webpack's code splitting feature: https://webpack.js.org/guides/code-splitting/#src/components/Sidebar/Sidebar.jsx

How to solve webpack2 error: You may need an appropriate loader to handle this file type?

I am trying to convert my reactjs/webpack/gulp app to webpack2. I am using the webpackconfig+.babelrc file and package.json from this project as a starting point:
https://github.com/ModusCreateOrg/budgeting-sample-app-webpack2
This is the gulpcode:
var gulp = require('gulp');
var webpackStream = require('webpack-stream');
var webpack2 = require('webpack');
gulp.task('default', function() {
return gulp.src('app/app.js')
.pipe(webpackStream({/* options */}, webpack2))
.pipe(gulp.dest('dist/'));
});
When I run 'gulp' I get this error:
stream.js:74
throw er; // Unhandled stream error in pipe.
^
Error: ./app/app.js
Module parse failed: C:\myapp\app\app.js Unexpected token (11:4)
You may need an appropriate loader to handle this file type.
|
| ReactDOM.render(
| <Provider>
| <App />
| </Provider>,
Which loader do I need and where do I configure this?
You're not actually using webpack.config.js so presumably you're configuring the options in the Gulpfile. But you commented the options as /* options */ which is the important bit, where you actually configure webpack.
You configure the loaders in these options under module.rules (see also Concepts - Loaders). In your case you need the babel-loader with babel-preset-react to be able to transpile JSX syntax, the preset should already be in the .babelrc config you're using. You just need to add the loader to your options in the Gulpfile so that your .js and .jsx files are passed through that loader (using the same rule as in the project you linked):
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
'babel-loader'
],
}
]
}
Instead of defining the options in your Gulpfile you can define a webpack.config.js and then just require it and pass it to webpackStream. This file is automatically used when you use webpack directly (without Gulp), so it's very convenient to have that config if you ever want to run it outside of Gulp. It's good idea to get familiar with webpack. A good starting point is the Core Concepts of the official docs.
Usually an object is exported, which you can use directly in webpackStream, but in the project you linked, it exports a function which returns the configuration object based on the environment used. To use it directly in your Gulpfile you would do the following:
var gulp = require('gulp');
var webpackStream = require('webpack-stream');
var config = require('./webpack.config');
gulp.task('default', function() {
return gulp.src('app/app.js')
.pipe(webpackStream(config()))
.pipe(gulp.dest('dist/'));
});
config() returns the development options and to get the production config you'd need to call config({ prod: true }). You probably don't want to use exactly that config but use your own which you can just export as a plain object, so you don't need to call a function.

React-router issues using static-render-webpack-plugin

I just started working with React last week, and I'm having trouble following a tutorial for the static-render-webpack-plugin.
I've put the code online at GitHub if you want to take a closer look.
After following the tutorial and making a couple of changes (I added babel-core, I changed the js loader to babel-loader and the entry point url needed a small correction), when I try to run webpack -p to generate the static files I get the following error:
ERROR in ./src/entry.js
Module build failed: SyntaxError: .../src/entry.js: Unexpected token (10:2)
8 |
9 | const routes = (
> 10 | <Route path="/" handler={RootPage}>
| ^
I think it might have something to do with the changes made with the latest version of react-router. I'm using the latest version, but the syntax for the tutorial looks like it might have been written prior to v.1.0. For example, I think the part of the tutorial that says to add this to the src/entry.js file:
if (typeof document != 'undefined') {
Router.run(routes, path, (Root) => {
React.render(<Root/>, document);
});
}
probably needs to be rewritten to something like this (but I'm not sure if this is quite right):
if (typeof document != 'undefined') {
ReactDOM.render(routes, document);
}
There's obviously more going on though since I get the same error message when I try that rewritten snippet then run webpack-dev-server -- which is the only time it should hit that code. (Yes, I added import ReactDOM from 'react-dom'; to the top of the page and "react-dom": "^0.14.7", to the package.json.)
I am sure this part (also on src/entry.js) needs to be rewritten to match the latest react-router too but I'm not sure how:
export default function(path, props, callback) {
Router.run(routes, path, (Root) => {
const html = React.renderToString(<Root/>);
callback('<!doctype html>' + html);
});
}
Thanks in advance for any help or hints you can give.
Your code is breaking because Webpack doesn't know how to transpile the JSX to ES5. You've specified babel-loader as your loader for JS files in your webpack config, but unfortunately Babel 6 does not do anything out of the box, you need to include "plugins" that contain the rules for compiling different syntaxes down to ES5. In this case, you'll want the es2015 preset to support all ES6 syntax, and the react preset to support JSX. You're also missing the extract-text-webpack-plugin you are trying to import into your webpack config. Snag these through NPM:
npm i -D babel-preset-2015 babel-preset-react extract-text-webpack-plugin
Then, add the presets to your webpack.config.js file in the loaders section for js/jsx files:
{
test: /\.(js|jsx)?$/,
loader: 'babel',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
I forked your repo and made these changes and was able to get a bit further through the compilation process. It seems like there are module dependencies specific to your project you'll still need to resolve.

Resources