I am trying to create a custom npm package that will allow me to import some of my components over multiple projects. I wrote a simple package yesterday which can be found here: demo npm package. It's a simple starter project that has a webpack config and a uses npx babel to transpile and copy the files to the dist and lib folder.
If I include this package into my own project it works but not as I would expect. when I use the following code:
import {NavBar, HelloLib} from "testprivatenprodney;
It gives an error "Module not found".
when I use
import { NavBar, HelloLib } from "testprivatenprodney/lib/HelloLib";
it works as long as the navBar component does not have any child components. If it has I get "Module not found" error again.
I think I am missing something in my webpack configuration. yet all I can find is to have the resolve array, which is included.
const webpack = require("webpack");
module.exports = {
devtool: "source-map",
entry: "./src/index.js",
output: {
path: __dirname + "/dist",
publicPath: "/",
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.css$/,
loaders: ["style-loader", "css-loader"]
}
]
},
resolve: {
extensions: [".js", ".jsx"]
},
plugins: [
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
})
]
};
any help would be much appreciated.
Related
My organization has a custom build datatable that is built with React, compiled and used in several other applications. One of those other applications is itself a React app. We recently updated our larger react app so that we're using the latest builds on several npm packages, and the datatable build stopped working within react. I decided to try building the datatable in webpack the same way to get them working again, but I can't seem to produce a file that builds the datatable react into something I can import as a local package.
Here's the webpack.config.js I'm using to build the datatable. Any advice would be very welcome.
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = [
{
entry: './src/react/datatable/datatable-component.jsx',
externals: [nodeExternals()],
name: 'datatable-react',
output: {
path: path.resolve(__dirname, './dist/assets/js/datatable'),
filename: 'datatable.js',
chunkFilename: '[id].js',
publicPath: ''
},
mode: 'production',
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
}
},
];
I have an issue about Storybook. I can't start storybook and I have an error about my SCSS file.
Here is the error:
ModuleParseError: Module parse failed: Unexpected token (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
.h1 {
| color: red;
| }
at handleParseError (/myproject/node_modules/#storybook/builder-webpack4/node_modules/webpack/lib/NormalModule.js:469:19)
I mean this is juste a simple class. But when the file is empty, the compilation is okay, so I don't understand how I can resolve this.
My SCSS file
.h1 {
color: red;
}
My Webpack file
const webpack = require('webpack');
const path = require('path');
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, './src/index.js'),
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.scss?$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|jpe?g|gif)$/i,
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
},
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js',
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
contentBase: path.resolve(__dirname, './dist'),
hot: true,
},
};
My main.js file in the .storybook folder
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)",
"../src/**/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials"
]
}
Is anyone has a solution please?
Thanks by advance
Finally, I have solved my problem, so here is how I did it.
First of all, I uninstalled the storybook (How to remove storybook from the react project), then the reinstalled via webpack (https://storybook.js.org/blog/storybook-for-webpack-5/).
For once with Webpack it works whereas installing it with NPM (or Yarn for my part) brought me to the complications that I had posted above. My guess is that it works for Webpack 5, whereas with NPM, I was getting an error about the css-loader loader that told me about Webpack 4.
Storybook worked, but I was still worried about .scss files. My terminal told me that I did not have a specific loader. So I took a loader for this type of file by adding a webpack.config.js in the .storybook folder created when we install Storybook. I used the instructions found here: https://storybook.js.org/docs/react/configure/webpack
About Sass files: Storybook is case sensitive, and also doesn't take into account files starting with _, so not possible to use partials
I hope you don't have this kind of problem, but if you do, maybe these answers will help you ^^
I am building a simple React app from scratch using Webpack.
I was finally able to run the dev server and when I tried to apply some styles via CSS, the files wouldn't load and I assume my Webpack 4 configuration is not right.
Here is the code:
webpack.config.js
// const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
module.exports = {
mode: 'development',
entry: ['./src/index.js'],
resolve: {
extensions: [".js", ".jsx"]
},
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist',
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 8080
},
module: {
rules: [
{
test: /\.js|.jsx$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: ["react"]
}
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader'
}
]
},
};
My project structure is like this, I will include only src because it lives in the root:
**src**
|_assets
|_componentns
|_styles
|_App.css
|_index.css
App.jsx
index.js
index.html
I would like to be able to add multiple css files for each component I have and apply them, and to be able to style the index the index.html.
Thank you very much for your help.
Your webpack configuration looks fine.
make sure you import the required css files in your components.
import "./App.css";
class App extends Component {
render() {
return (
<div>
<Child />
</div>
);
}
}
All you have to do is import the CSS files when needed as you would a JavaScript module. So if you want to have a style sheet for your whole application, you can import a global stylesheet in your index.js.
import './styles/index.css';
and you can do the same for each component with specific styles
import './styles/App.css'
in which case you might want to setup CSS modules to avoid overlapping class names.
Ok, rookie mistake here, the way I ahve set up webpack is I have to build it first and then run the dev server, no the other way around.
All answers above are valid and helpful, I just forgot to run build after changes.
I have a fairly basic webpack setup that runs babel and out comes my minified js with a source map.
Now when I run my source map in chrome I get the js before babel and before minification. However I would often like to have my source map after babel but before minification. Is this possible?
TL;DR I want source map to post-babel pre-minifcation. Possible?
For completeness
I run babel-loader 8 with webpack 4
Here is a screenshot from chrome showing the problem. As you can see the Dropzone tag indicates this is jsx (and so before babel)
Secondly here is my webpack config (not that it actually matters for my question).
const path = require('path');
module.exports = {
context: path.join(__dirname, 'Scripts', 'react'),
entry: {
client: './client'
},
output: {
path: path.join(__dirname, 'Scripts', 'app'),
filename: '[name].bundle.min.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: [require('#babel/plugin-proposal-object-rest-spread')],
presets: ["#babel/es2015", "#babel/react", "#babel/stage-0"]
}
}
}
]
},
resolve: {
extensions: ['.js', '.jsx']
},
externals: {
// Use external version of React (from CDN for client-side, or
// bundled with ReactJS.NET for server-side)
react: 'React'
},
devtool: 'source-map'
};
Running webpack with -d gives a second set of source maps in chrome that does the trick.
As I write webpack.config.js like this
module.exports = {
entry: './index.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}]
}
};
And in index.jsx I import a react module App
import React from 'react';
import { render } from 'react-dom';
import App from './containers/App';
let rootElement = document.getElementById('box')
render(
<App />,
rootElement
)
I find if I named module app in App.jsx, then webpack will say in index.jsx can't find module App, but if I named named module app in App.js, it will find this module and work well.
So, I'm confuse about it. In my webpack.config.js, I have writed test: /\.jsx?$/ to check file, but why named *.jsx can't be found?
Webpack doesn't know to resolve .jsx files implicitly. You can specify a file extension in your app (import App from './containers/App.jsx';). Your current loader test says to use the babel loader when you explicitly import a file with the jsx extension.
or, you can include .jsx in the extensions that webpack should resolve without explicit declaration:
module.exports = {
entry: './index.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}]
},
resolve: {
extensions: ['', '.js', '.jsx'],
}
};
For Webpack 2, leave off the empty extension.
resolve: {
extensions: ['.js', '.jsx']
}
In the interest of readability and copy-paste coding. Here is the webpack 4 answer from mr rogers comment in this thread.
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
resolve: {
extensions: [".js", ".jsx"]
},
use: {
loader: "babel-loader"
}
},
]
}
Adding to the above answer,
The resolve property is where you have to add all the file types you are using in your application.
Suppose you want to use .jsx or .es6 files; you can happily include them here and webpack will resolve them:
resolve: {
extensions: ["", ".js", ".jsx", ".es6"]
}
If you add the extensions in the resolve property, you can remove them from the import statement:
import Hello from './hello'; // Extensions removed
import World from './world';
Other scenarios like if you want coffee script to be detected you should configure your test property as well like:
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
},
resolve: {
// you can now require('file') instead of require('file.coffee')
extensions: ['', '.js', '.json', '.coffee']
}
};
As mentioned in the comments on the answer from #max, for webpack 4, I found that I needed to put this in one of the rules that were listed under module, like so:
{
module: {
rules: [
{
test: /\.jsx?$/,
resolve: {
extensions: [".js", ".jsx"]
},
include: ...
}
]
}
}
Verify, that bundle.js is being generated without errors (check the Task Runner Log).
I was getting 'can't find module if file named jsx' due to the syntax error in html in component render function.
I was facing similar issue, and was able to resolve using resolve property.
const path = require('path');
module.exports = {
entry: './src/app.jsx',
output: {
path: path.join(__dirname,'public'),
filename: 'bundle.js'
},
module : {
rules: [{
loader: 'babel-loader',
test: /\.jsx$/,
exclude: /node_modules/
}]
},
resolve: {
extensions: ['.js', '.jsx']
}
}
As You can see I have used .jsx in there which resolved following error
ERROR in ./src/app.jsx
Module not found: Error: Can't resolve
For Reference: https://webpack.js.org/configuration/resolve/#resolve-extensions
I faced similar issue with imports while building my typescript project having the following webpack dependencies:
"webpack": "^5.28.0",
"webpack-cli": "^4.5.0"
So, I had a App.tsx file present in the correct path and exported with named export. But, yarn build was failing with Module not found: Error: Can't resolve './App' in '/app/sample_proj/src'. The relevant code for this error is: import {App} from './App';. To fix this, I had to add .tsx under webpack known extensions. Sample entry from webpack.config.js is :
module.exports = {
......
resolve: {
extensions: [ '.ts', '.js', '.tsx', '.jsx'],
}
}
Also, for this error, it does not matter, if the imports are default or named. webpack only needs to know the kind of file extensions it should deal with.
I found restarting my server fixed this issue. simply run
npm start