I am attempting to use foundation in the react-static site I am creating. Everything is working great while using npm start to start a local node server with live reloading, however I am not able to successfully build my site with npm run build.
The error that I keep encountering is:
/Users/abroccoli/Documents/apm.net/apm-react-static/node_modules/foundation-sites/dist/js/npm.js:1
(function (exports, require, module, __filename, __dirname) { import $ from 'jquery';
^^^^^^
SyntaxError: Unexpected token import
Through my research into webpack and react-static and node.js, I believe that node is having an issue with the ES6 syntax of the foundation-sites file. However, react-static is written in ES6 and uses import at the beginning of every file.
I am using the basic webpack configuration that comes with react-static and should include the proper loaders for parsing ES6 with Babel, according to the README.
webpack: (config, { defaultLoaders, stage }) => {
config.module.rules = [
{
oneOf: [
{
test: /\.s(a|c)ss$/,
use:
stage === 'dev'
? [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'sass-loader' }]
: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: true,
sourceMap: false,
},
},
{
loader: 'sass-loader',
options: { includePaths: ['src/'] },
},
],
}),
},
defaultLoaders.cssLoader,
defaultLoaders.jsLoader,
defaultLoaders.fileLoader,
],
},
]
return config
},
I suspect that I am not loading foundation-sites in properly. How can I get foundation-sites to work when I go to build my react-static site?
Update node to be able to use the new ES6 standard.
Related
Trying to setup a react-app with all latest versions.
Github Repo Link
Trying to run storybook with sass file imported will result in below error. Trying to run without importing the styles, storybook works.
The same code works correctly when its run as npm start run with no warnings and errors.
I have configured css modules using #dr.pogodin/babel-plugin-react-css-modules with sass, webpack 5, react 17 and with latest packages.
ERROR in ./src/assets/stylesheets/app.scss 1:0
Module parse failed: Unexpected character '#' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> #import "./base.scss";
| #import "./generics/font.scss";
| #import "./generics/spacing.scss";
# ./stories/index.js 5:0-44 8:2-10:4 8:58-10:3 9:4-49
# ./src/components/atoms/button/stories.js
babel.config.js
module.exports = {
presets: ["#babel/preset-env", "#babel/preset-react"],
plugins: [
[
"#dr.pogodin/babel-plugin-react-css-modules",
{
webpackHotModuleReloading: true,
autoResolveMultipleImports: true,
filetypes: {
".scss": {
syntax: "postcss-scss",
},
},
generateScopedName: "[name]__[local]___[hash:base64:5]",
},
],
],
};
webpack.config.js for css (partial code inlcuded)
{
test: /\.(css|sass|scss)$/,
exclude: /node_modules/,
use: [
isDev ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
auto: (resourcePath) =>
resourcePath.indexOf("assets/stylesheets") === -1,
localIdentName:"[name]__[local]___[hash:base64:5]",
},
sourceMap: true,
},
},
"sass-loader",
],
}
storybook/webpack.config.js file
const custom = require('../webpack.config.js');
module.exports = {
// stories: ['../src/components/**/*.stories.js'],
webpackFinal: (config) => {
return {
...config,
module: {
rules: custom.module.rules,
},
resolve: {
...config.resolve,
...custom.resolve,
}
};
},
};
I don't know what you have done with your configuration but you would define the config things inside .storybook/main.js. And for global style css is supposed to be included in preview.js file.
In short, you have to do the few things:
Remove your .storybook/config.js and add .storybook/main.js with following content:
const custom = require('../webpack.config.js');
module.exports = {
stories: [
'../src/**/stories.js', // The name should have a prefix for component name like `button.stories.js` instead of `stories.js` like you've done. As you renamed, you can remove this pattern
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
webpackFinal: (config) => {
return {
...config,
module: {
rules: custom.module.rules,
},
resolve: {
...config.resolve,
...custom.resolve,
}
};
},
};
Create the .storybook/preview.js to import your global style:
import "../src/assets/stylesheets/app.scss";
Some people have been running into problems a some scss preset when using Storybook 6.2.0 with Webpack 5. Instead of using a preset, I recommend configuring the Webpack config in main.js as mentioned above. Here's the relevant portion of a working Storybook Webpack config for Sass:
module: {
...config.module,
rules: [
...config.module.rules,
{
test: /\.(scss)$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: function () {
return [require('precss'), require('autoprefixer')];
},
},
},
},
{
loader: require.resolve('sass-loader'),
options: {
implementation: require('sass'),
},
},
],
},
],
},
I've written more about getting Storybook off the ground with Webpack 5 (and modifying the Storybook Webpack config) over here.
Another reason this might happen: if you are adding new components to your app and the path defined for your sass-loader does not match anymore.
E.g. if you have this in your .storybook/main.js:
webpackFinal: async config => {
// Add SASS support
// https://storybook.js.org/docs/configurations/custom-webpack-config/#examples
config.module.rules.push({
test: /\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: {
compileType: "icss",
},
},
},
"sass-loader",
],
include: path.resolve(__dirname, "../"),
})
Update or completely remove the include path.
I used create-react-app to create a react application.
After I run eject, I am unable to use the spread operator as follows:
//eslint-disable-next-line
const { children, ...attributes } = this.props; //Line 19
It keeps giving me this error when I run yarn start
Line 19: Parsing error: Unexpected token ..
Webpack Dev Server
I have tried adding all the presets and the transform plugin to both webpack dev server config and .babelrc but no luck
// Process JS with Babel.
{
test: /\.(js|jsx|mjs)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
presets:['react','es2015','env',"stage-2"],
plugins: ["transform-object-rest-spread"],
// 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,
},
},
// "postcss" loader app
And in the babel rc file as well
//.babelrc
{
"presets":["env","react","stage-2"],
"plugins": [
["transform-object-rest-spread", { "useBuiltIns": true }]
]
}
It works fine if I don't eject the script.
So the problem turned out to be eslint.
Webpack config was loading it before babel
Adding parser options fixed it.
{
test: /\.(js|jsx|mjs)$/,
enforce: 'pre',
use: [
{
options: {
formatter: eslintFormatter,
eslintPath: require.resolve('eslint'),
"extends": "airbnb",
"parserOptions":{
"ecmaFeatures": {
"experimentalObjectRestSpread": true
}
}
},
loader: require.resolve('eslint-loader'),
},
],
include: paths.appSrc,
},
Updated the #babel with this:
npm install #babel/runtime#latest did the work
CLI Tool: Storybook
Framework: Vue/ Nuxt
Issue: I'm trying to pull in global SCSS variables to Storybook Stories so they run the components the same way as they do in Nuxt, I've tried the custom webpack config with sass-resources-loader but had no luck, just wanted to check if anyone else has already solved this problem
It seems to be an issue with Storybook handling multiple rules.
I solved it by a work around.
You can read the blog i wrote for detailed explaination here.
Below is my webpack config - main.js :
webpackFinal: async (config, { configType }) => {
config.module.rules.map((rule) => {
if (rule.oneOf) {
rule.oneOf = rule.oneOf.slice().map((subRule) => {
if (subRule.test instanceof RegExp && subRule.test.test('.scss')) {
return {
...subRule,
use: [
...subRule.use,
{
loader: require.resolve('sass-resources-loader'),
options: {
resources: [
path.resolve(__dirname, '../src/styles/_common.scss')
]
}
}
],
}
}
return subRule;
});
}
return rule;
});
return config;
},
Hope this helps someone!
I encountered the issue where global SASS variables were causing Storybook for Vue to fail.
For me, creating a webpack.config.js file in the .storybook folder with the below configuration solved my problem:
module.exports = (storybookBaseConfig, configType, defaultConfig) => {
defaultConfig.module.rules.push(
{
resourceQuery: /module/,
use: [
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
{
loader: 'sass-loader',
options: {
sourceMap: false,
indentedSyntax: true,
data: '#import "#/sass/_variables.scss";'
}
}
]
}
);
return defaultConfig;
};
Note the line data: '#import "#/sass/_variables.scss";' needs to match the file path for the SASS file with variables in your project.
This section of config was retrieved from Vue CLI 3 by running vue inspect > output.js and then copying the config for the rule test: /\.sass$/.
You need to add the scss rule in your .storybook/webpack.config.js for storybook to parse scss.
const path = require('path');
const scss = {
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
],
};
module.exports = (storybookBaseConfig, configType, defaultConfig) => {
defaultConfig.module.rules.push(scss);
return defaultConfig;
};
You may also need to install the appropriate loaders:
yarn add -D vue-style-loader sass-loader css-loader
For anybody who can actually get Storybook to read SCSS files but can't get it to read the global variables file, do this in your custom webpack config:
module: {
rules: [
// Apply loader
{
test: /\.scss$/,
loaders: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
prependData: '#import "path/to/global.scss";',
},
},
],
},
],
}
If your components do not get styles applied when run in the Storybook component explorer UI, just import SASS styles in your main Storybook config/storybook/config.js (in previous versions was by default at storybook/config.js) like so:
// Import Styles
import '../../src/assets/styles/index.scss';
Usually you'd have your styles and plugins imported in your src/main.js / src/main.ts but you also need to do this in Storybook config, as when running Storybook it's not running the whole Vue app but just those individual components.
I am trying to setup my react project so I can use SASS in the SCSS format.
This is in my webpack.config.dev.js:
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
},
},
{
loader: require.resolve('sass-loader'),
}
]
}
I import the scss files into my jsx in two different ways:
import './index.scss';
import css from './ModalWrapper.scss';
When I run the app I am currently getting the error:
./src/index.scss
Module build failed:
body {
^
Invalid CSS after "m": expected 1 selector or at-rule, was "module.exports = __"
in /pathtoapp/web/src/index.scss (line 1, column 1)
It appears me, that one, react is trying to interpret the SCSS as CSS which should work. In addition, react believes that body is not valid CSS. There, I would believe that neither CSS or SCSS are being loaded correctly.
Any help would be appreciated. There are quite a few unanswered questions to this problem.
If you are on Webpack 3, add this to module.rules
{
test: /\.scss$/,
loader: [
require.resolve('style-loader'),
require.resolve('css-loader'),
require.resolve('sass-loader'),
]
},
And then add the file loader and make sure to add .scss to the array of the key exclude like this
{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// it's runtime that would otherwise processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.js$/, /\.html$/, /\.json$/, /\.scss$/,],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
}
And of course, make sure you have style-loader, sass-loader, css-loader and file-loader in you package.json. This code snippet worked for me when using the latest version of create-react-app.
This is what ended up working for me:
{
test: /\.scss$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
localIdentName: "[local]___[hash:base64:5]",
},
}, {
loader: 'sass-loader',
options: {
outputStyle: "expanded",
sourceMap: true,
},
}]
},
I'm sure the other answers are just as good, but for maximum brevity, this works for me (I erased some of the internal webpack.config.dev.js comments presumably made by the create react folks):
module: {
strictExportPresence: true,
rules: [
{
test: /\.scss/,
use: ['style-loader','css-loader', 'sass-loader']
},...
I don't know if it matters, but I put this on the top. Also, yes, make sure to add the scss file to the excluded array as mentioned above.
For some reason my yarn run dev command is failing due to the following:
SyntaxError: /src/components/home/index.scss:Unexpected token (1:0)
> 1 | .home {
...
I'm using webpack 2.2.0 which is setup like so:
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
include: path.resolve(__dirname, 'src'),
}, {
test: /\.(scss)/,
include: path.resolve(__dirname, 'src'),
use: [
'style-loader',
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]__[hash:base64:5]',
'sass-loader',
{
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('autoprefixer')
]
}
}
}
],
include: path.resolve(__dirname, 'src')
}
]
}
And all I'm doing in my index.js component is import s from './styles.scss'. If I remove the import statement and allow the app to boot and then put the import statement back in while the app is running and refresh the page then the styles are present... I find this extremely odd and haven't encountered this issue before...
That thread explains the reason why you are getting this error:
I think I found out why it didn't work on the first place. Though Webpack allows requiring static assets on the client side, babel, which compiles the server code, fails to do so as on the server side Node's require understands only JS files. This means that server side rendering is not possible with the default Webpack and babel.
There are several solutions to solve that issue, more or less complex to put in place.
The easiest one, is to ignore .scss on the server as so:
I added a run-server.js file to the project
require('babel-core/register')({
presets: ['es2015-node5', 'stage-0'],
plugins: ['transform-decorators-legacy'] //was needed to support decorators
})
require.extensions['.scss'] = () => {
return;
}
require.extensions['.css'] = () => {
return;
}
require('./server')
Run that with instead:
"cross-env NODE_ENV=development node ./run-server.js"
Added to your project:
npm install babel-preset-es2015-node5 babel-plugin-transform-decorators-legacy -D