Webpack load module outside the root directory - reactjs

I am using Webpack to build my react-redux apps and encountered a situation:
I tried to take some common components out of one app directory in order to reuse them during multiple react app, but when I tried to load one component outside the app directory I got errors:
Module build failed: SyntaxError: D:/dev/gdas/WebContent/reactx/common/components/HeaderFooter/Header.js: Unexpected token (74:31)
My babel-loader rule in webpack.config.js is as below:
{
test: /\.jsx?$/,
include: [path.resolve(__dirname, 'src'), path.resolve(__dirname, '../reactx/common/components')],
loader: 'babel-loader'
}
and My import code is as below:
import Header from '../../../reactx/common/components/HeaderFooter/Header.js'
Is that any solution to fix this issue?

You're doing everything right. It's just that this file D:/dev/gdas/WebContent/reactx/common/components/HeaderFooter/Header.js has a SyntaxError at 74:31

Related

How do I share components with external Sass stylesheets in ReactJS

I am trying to build a monorepo for my React projects as most of the code is shared between a few of my projects. I am using Yarn workspaces and Lerna for this.
I have managed to get a basic example working where the React component is shared between two projects. In this working example, however, the stylesheet is a plain CSS stylesheet and is correctly imported.
I am using Babel to transpile the React and ES6 code.
lerna exec --scope shared -- babel src -d dist --copy-files
where shared is my package containing shared components. Above command puts the transpiled JS and CSS files in the dist folder.
However, I have .scss files in my actual code base. Hence trying to replace external CSS file with external SCSS file in the example project. However, it doesn't work. The stylesheet isn't applied.
I think I understand why it must not be working. In CRA project whenever we use .scss file I think Webpack preprocesses these into .css files. In this is not happening hence the issue. Correct me if I am wrong.
I tried using Webpack instead of Babel. However, the issue that I faced was Webpack bundled all files into a single file which is something I don't want. I want that the individual component file should be transpiled and kept in the same folder structure under dist. Please see the folder structure below. shared is the package with shared components and myapp package uses the shared components.
workspace
--packages
--shared
--dist
--components
--button
--Button.js
--Button.scss
--header
--Header.js
--Header.scss
--src
--components
--button
--Button.js
--Button.scss
--header
--Header.js
--Header.scss
---myapp
My webpack.config.js
// Webpack uses this to work with directories
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
// Path and filename of the result bundle.
// Webpack will bundle all JavaScript into this file
output: {
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'commonjs2'
//filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
}
},
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.(jpg|png|gif|svg|tiff)$/, use: 'file-loader' },
{ test: /\.(woff|woff2|eot|ttf|otf)$/, use: 'file-loader' }
]
}
};
I am stuck at this point as I am not sure how I can import SCSS file in my React component which can be shared.
I'm not sure if there is a way to tell Webpack and Babel to transpile the React files and just put them in the dist folder without bundling them into a single file and also to preprocess the .scss files and use them in the transpiled files.

react js exclude a component of webpack bundle

I created an app with react-create-app, which generated a webpack config. But now, I would like to exclude a component of the bundle webpack because this component contains config info that must be modified. I read a lot about externals and exclude config with webpack but unfortunately none seems to work for me. In my case, here is my src folder:
-views
-config
|-ConfigCtl.js
-App.js
...
I want to exclude the file ConfigCtl.js. I tried to put this in the webpack.config.dev.js file at the modules.export section:
externals: {
"./src/config/ConfigCtl.js": "ConfigCtl"
}
But the ConfigCtl file is always packed in the bundle...
Is not a duplicate of other subject. I've tried the solution proposed in this subject but without efficiency...
Any suggestions ?
If you are using react with webpack go to your webpack config file and in the rule that test for /.js$/ there is a section to exclude dir or files from the bundle.Once this is done the file will be excluded from the bundle.
module:{
rules:[
{
test: /\.js$/,
exclude: /node_modules/,"./src/config/ConfigCtl.js"
use: {
loader: "babel-loader"
}
}

Angular 2 and Webpack - url() in SASS file cannot resolve even with resolve-url-loader

I started my Angular 2 Webpack project from this official guide.
I went ahead and ran npm install --save-dev node-sass sass-loader resolve-url-loader. That went well.
My component is sitting at root/src/app/mycomponent/mycomponent.ts, and I'm referencing my scss in the heading this way:
#Component({
selector: 'home',
templateUrl: './mycomponent.html',
styleUrls: ['./mycomponent.scss']
})
The scss file is at root/src/app/mycomponent/mycomponent.scss and I have the following SASS in there:
p{
color: blue;
background-image: url('./background.jpg');
}
That image is sitting at root/src/app/mycomponent/background.jpg.
In webpack.common.js I have the following rule for .scss files:
{
test: /\.scss$/,
exclude: 'node_modules',
loaders: ['style-loader','css-loader','resolve-url-loader','sass-loader?sourceMap']
}
as recommended by resolve-url-loader documentation.
I keep on getting this error:
ERROR in ./~/css-loader!./~/resolve-url-loader!./~/sass-loader/lib/loader.js?sourceMap!./src/app/mycomponent/mycomponent.scss
Module not found: Error: Can't resolve './background.jpg'
I even tried loaders: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader!sass-loader?sourceMap!resolve-url-loader'}) and I'm still getting the same error.
For the life of me, I can't figure out what I did wrong. I was under the impression that resolve-url-loader will let me put a location in SASS url() relative to the .scss file it's declared in! That background.jpg sits in the same folder as my .scss file, so I think I referenced the path correctly.
I searched SO and the web and nobody seems to have the right solution. Is there any other code I need to show? Please help! And please, I don't want to import or require image files from .ts.
Update
It turns out that I misspelled the name of the image's file name. Now, I don't get that "module not found" error.
HOWEVER I now get the error in the browser's console output: Expected 'styles' to be an array of strings. This is with the configuration
loaders: ['style-loader','css-loader','resolve-url-loader','sass-loader?sourceMap']
Still stuck.
According to the error message, Angular is expecting assets to be strings while resolving the code. Thus in this situation, we need another loader here:
npm install --save-dev css-to-string-loader
Then in your webpack config file:
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['css-to-string-loader', 'css-loader', 'resolve-url-loader', 'sass-loader?sourceMap']
},
It should be good to go now.
I managed to get passed this issue by using 'exports-loader' instead of 'style-loader'
eg:
'exports-loader?module.exports.toString()'

Multiple webpack alias configurations can't resolve modules

I am working on an Angular 2 application written in Typescript, that is using webpack in conjunction with ts-loader to bundle everything together.
I am relying heavily on webpack's resolve.alias to cater for different build outputs and I have come across an issue.
When running a specific build, ts-loader is throwing an error saying it can not find a module that is used in the current build. This, I would assume, is due to the alias pointing to a different file.
eg:
file: myApp.ts
import {Logger} from 'logger';
export class myApp {}
I have two alias JSON files, one is setup to point 'logger' at remoteSystemLogger.ts, and another which points at consoleLogger.ts
Build A will use remoteSystemLogger,
Build B will use consoleLogger
Now each logger class will import their relative dependencies. For instance:
file: remoteSystemLogger.ts
import {HTTP} from 'http';
export class Logger {}
The problem is, that when I run build B, I am getting an error saying:
ERROR in remoteSystemLogger.ts
error TS2307: Cannot find module 'http'.
http as well as remoteSystemLogger is currently not specified in the alias JSON file for Build B, as Build B should have no dependency on it.
The alias file that get's used for the webpack build is determined at build time via a param.
Here is an example of the resolve used in webpack config
let moduleAliasingConfig = `./alias/${buildType}.json`
// ....
resolve: {
root: [
path.resolve('.'),
path.resolve('node_modules')
],
alias: moduleAliasingConfig,
extensions: ['', '.ts', '.js']
},
And here is the ts-loader config:
loaders: [
{test: /\.ts$/, loaders: ['ts'], exclude: [/\.(spec|e2e)\.ts$/]}
]
I am not sure if maybe I have miss-configured something, or this is an issue with either the loader, webpack's resolver, or just my understanding of how the aliasing works.
As my understanding is, that webpack will traverse through my import/dependency tree, based on the alias file and my entry point.
Additional env info:
package.json setup:
"ts-loader": "^1.2.1",
"webpack": "^1.13.0"

ERROR in ./~/react-network-diagrams/lib/map.css

I am wanting to use the react-network-diagrams library. I have node v0.10.25, npm version 1.3.10 installed and am able to run .js files using node. I have followed tutorials to install webpack and babel and these both appear to be working with the tutorial examples. I have installed the react-network-diagram components using npm. This initially complained that my sibling dependencies we wrong. This seamed to be fixed when I reloaded the react and react-dom and gave a specific version (npm install --save react#^0.14.3 react-dom#^0.14.3)
So everything seems to work according to the tutorials.
Here is the index.jsx file contents:
console.log( "hw" )
import React from 'react';
import {render} from 'react-dom';
import { TrafficMap } from "react-network-diagrams";
class App extends React.Component {
render () {
return <TrafficMap width={980} height={500} margin={50}
topology={topo}
traffic={traffic}
edgeColorMap={edgeColorMap}
edgeDrawingMethod="bidirectionalArrow"
edgeThinknessMap={edgeThinknessMap}
edgeShapeMap={edgeShapeMap}
nodeSizeMap={nodeSizeMap}
nodeShapeMap={nodeShapeMap}
stylesMap={stylesMap}
selection={mapSelection}
onSelectionChange={this.handleSelectionChanged} />
//return <p> Hello React!</p>;
}
}
render(<App/>, document.getElementById('app'));
And here is output of webpack
ubuntu#ip-172-31-38-114:~/doe2$ ./node_modules/.bin/webpack -d
Hash: 1ecd317731574aa4e7fd
Version: webpack 1.13.0
Time: 5901ms
Asset Size Chunks Chunk Names
bundle.js 1.38 MB 0 [emitted] main
bundle.js.map 1.55 MB 0 [emitted] main
+ 204 hidden modules
ERROR in ./~/react-network-diagrams/lib/map.css
Module parse failed: /home/ubuntu/doe2/node_modules/react-network-diagrams/lib/map.css Unexpected token (1:4)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (1:4)
at Parser.pp.raise (/home/ubuntu/doe2/node_modules/webpack/node_modules/acorn/dist/acorn.js:920:13)
at Parser.pp.unexpected (/home/ubuntu/doe2/node_modules/webpack/node_modules/acorn/dist/acorn.js:1483:8)
at Parser.pp.semicolon (/home/ubuntu/doe2/node_modules/webpack/node_modules/acorn/dist/acorn.js:1462:73)
at Parser.pp.parseExpressionStatement (/home/ubuntu/doe2/node_modules/webpack/node_modules/acorn/dist/acorn.js:1976:8)
at Parser.pp.parseStatement (/home/ubuntu/doe2/node_modules/webpack/node_modules/acorn/dist/acorn.js:1754:188)
at Parser.pp.parseTopLevel (/home/ubuntu/doe2/node_modules/webpack/node_modules/acorn/dist/acorn.js:1648:21)
at Parser.parse (/home/ubuntu/doe2/node_modules/webpack/node_modules/acorn/dist/acorn.js:1616:17)
at Object.parse (/home/ubuntu/doe2/node_modules/webpack/node_modules/acorn/dist/acorn.js:882:44)
at Parser.parse (/home/ubuntu/doe2/node_modules/webpack/lib/Parser.js:902:15)
at DependenciesBlock.<anonymous> (/home/ubuntu/doe2/node_modules/webpack/lib/NormalModule.js:104:16)
at DependenciesBlock.onModuleBuild (/home/ubuntu/doe2/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:310:10)
at nextLoader (/home/ubuntu/doe2/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:275:25)
at /home/ubuntu/doe2/node_modules/webpack/node_modules/webpack-core/lib/NormalModuleMixin.js:259:5
at Storage.finished (/home/ubuntu/doe2/node_modules/webpack/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:38:16)
at /home/ubuntu/doe2/node_modules/webpack/node_modules/enhanced-resolve/node_modules/graceful-fs/graceful-fs.js:78:16
at fs.js:268:14
at /home/ubuntu/doe2/node_modules/webpack/node_modules/enhanced-resolve/node_modules/graceful-fs/graceful-fs.js:43:10
at Object.oncomplete (fs.js:107:15)
# ./~/react-network-diagrams/lib/map-base.js 55:0-20
The information given in the react network diagrams website (http://software.es.net/react-network-diagrams/#/?_k=xs005u) is unclear to me. Under the heading Examples it says I must run npm install. I have done this is several different directories but it hasn't helped and I am working somewhat in the dark. npm run web-site is a script within the package and it seems to do something but then it says to connect with a webclient to port 8080 but there is nothing listening there.
I just feel like I missing one or two crucial bits to bring the whole thing together.
Thanks for help.
Ian.
It looks like you are missing webpack's css loader configuration.
1) First install the css-loader (imports the css), and style-loader (adds the css to the DOM)
npm install css-loader style-loader --save-dev
2) Add the loader configuration to your webpack config
{
// ...
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
}
You could find some more information here Webpack: EMBEDDED STYLESHEETS
Promises are part of ES2015 (previously ES6). They are not yet integrated into all environments, including yours. There is a very well-known library that adds support for new ecmascript features, which is called Babel.js.
Just like we added a css-loader, we are going to add a babel-loader:
npm install babel-loader babel-core babel-preset-es2015 --save-dev
Now add to your loaders:
{
// ...
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" },
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel', // 'babel-loader' is also a legal name to reference
query: {
presets: ['es2015']
}
}
]
}
}
For more information: babel-loader

Resources