Invoking bundle.js built via webpack from create react app - javascript

I have created a bundle.js file with webpack from my create-react-app project as it sits with the below config:
const path = require("path")
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const glob = require("glob")
module.exports = {
entry: {
"bundle.js": glob.sync("build/static/?(js|css)/*.?(js|css)").map(f => path.resolve(__dirname, f)),
},
output: {
filename: "release/bundle.min.js",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [new UglifyJsPlugin()],
}
And, this is my index.html
<html>
<body id="root">
<script src="path-to-bundle.min.js"></script>
</html>
But, I dont see anything mounted inside #root. Basically the script does not fire. I tried the var and EntryPoint webpack config as well. In that case, EntryPoint is always an empty object.
UPDATE:
Package.json
"start": "react-scripts start",
"test": "react-scripts test",
"eject": "react-scripts eject",
"build": "npm run build:react && npm run build:bundle",
"build:react": "react-scripts build",
"build:bundle": "webpack --config webpack.config.js"

Related

Exposing variables from a library with webpack

I don't seem to understand how webpack works. I would like to create a plain javascript library with some reusable components that I can use in other applications and in script tags in the html. So I tried to make a very simple library that exposes one variable containing a string. Should be simple I thought, but can't seem to get it to work.
My webpack.config.js:
const path = require('path');
module.exports = {
entry: './src/app.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
library: {
name: 'mypack',
type: 'umd',
},
},
devtool: 'source-map',
devServer: {
watchContentBase: true,
contentBase: path.resolve(__dirname, 'dist'),
port: 9000
},
module: {
rules: [
{
test:/\.css$/,
use:['style-loader', 'css-loader']
}
]
},
}
My package.json:
{
"name": "mypack",
"version": "0.0.1",
"main": "./src/app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"start": "webpack ./src/app.js -d eval --watch --mode development",
"dev": "npx webpack serve"
},
"author": "me",
"license": "ISC",
"devDependencies": {
"css-loader": "^6.0.0",
"webpack": "^5.44.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
},
"dependencies": {
"style-loader": "^3.2.1"
}
}
My src/app.js
let myvar = "test";
export {myvar};
My dist/index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8"><title>test</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<script src="main.js"></script>
</head>
<body>
Test
<script>
console.log(mypack.myvar);
</script>
</body>
</html>
mypack.myvar gives an 'undefined' in the console. mypack seem to be an empty object {}.
How can I access myvar in my package? What am I doing wrong?
Of course, this is only a dummy, in reality I would like to expose objects from the package.
In the end it seems to be a problem with the webppack-dev-server.
If I comment out the line 'contentBase: path.resolve(_dirname, 'dist'),' from the webpack.config.js, copy the index.html to the root of my package and change the script tag source to "dist/index_bundle.js" then it works.
Not sure what is going on there, the script seems to load just fine in the situation above (in the sourceview in the browser, I can click the link and I see the generated javascript) but doesn't seem to be working at all. But that's another question.

Preact SSR hot reload/rebuild

I am trying to add automatic browser refresh to the dev environment for my preact ssr build.
package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start:client": "webpack -w",
"start:server": "babel-node server.js",
"dev": "yarn run start:client & yarn run start:server"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"#babel/cli": "^7.11.6",
"#babel/core": "^7.11.6",
"#babel/node": "^7.10.5",
"#babel/preset-env": "^7.11.5",
"babel-loader": "^8.1.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12"
},
"dependencies": {
"express": "^4.17.1",
"preact": "^10.5.2",
"preact-render-to-string": "^5.1.10",
"preact-router": "^3.2.1"
}
webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
path: path.join(__dirname, "dist"),
filename: "app.js"
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env']
}
}
}
]
},
mode: 'development'
};
server.js
const express = require('express');
const path = require('path');
const render = require('preact-render-to-string');
const { h } = require('preact');
const { App } = require('./src/App');
const app = express();
const HTMLShell = (html) => `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>preact ssr</title>
</head>
<body>
<div id="app">${html}</div>
<script src="./app.js"></script>
</body>
</html>
`;
app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', (req, res) => {
const html = render(<App />);
res.send(HTMLShell(html));
});
app.listen(3001);
When I run yarn dev, the webpack is correctly watching for any changes and rebuilding. I have to manually refresh the browser to see the effects, is there a way to automate this?
It doesn't look like you have webpack-dev-server as part of this project, which is responsible for handling the live reloading of your browser as changes occur. Start by adding that to your project:
yarn add webpack-dev-server --dev
Then, replace the current scripts in your package.json with the following:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start:client": "webpack-dev-server",
"start:server": "babel-node server.js",
"dev": "yarn run start:client & yarn run start:server"
},
Running yarn dev should give you live reload with recompiling after making that change.

Webpack not building the most recent changes

I am working on a fairly simple project from https://medium.com/ethereum-developers/the-ultimate-end-to-end-tutorial-to-create-and-deploy-a-fully-descentralized-dapp-in-ethereum-18f0cf6d7e0e
Since the tutorial doesn't focus on the frontend part(webpack and babel and other things), I picked up these steps from different places.
Now I was trying to build the front using webpack and http-server, but I realized that it is not updating with the changes that I am making to the file.
webpack.config.js
const path = require('path')
module.exports = {
entry: path.join(__dirname, 'src/js', 'index.js'), // Our frontend will be inside the src folder
output: {
path: path.join(__dirname, 'dist'),
filename: 'build.js' // The final file will be created in dist/build.js
},
module: {
rules: [{
test: /\.css$/, // To load the css in react
use: ['style-loader', 'css-loader'],
include: /src/
}, {
test: /\.jsx?$/, // To load the js and jsx files
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['#babel/preset-env', '#babel/preset-react']
}
}]
}
}
package.json
{
"name": "test-app",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.10.2",
"#babel/preset-env": "^7.10.2",
"#babel/preset-react": "^7.10.1",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.3",
"json-loader": "^0.5.7",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"style-loader": "^1.2.1",
"web3": "^0.20.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
},
"directories": {
"test": "test"
},
"dependencies": {},
"description": ""
}
I build it using
npx webpack --config webpack.config.js
and then serve it
http-server dist/
How do I fix this? And is this even the right way to do it?
Thanks.
U have already webpack-cli installed in your dependencies so u dont have to add config in command:
First Add Webpack Script in your Package.json:
"scripts": {
"watch": "webpack --watch",
},
When u run npm run watch --watch webpack will continue to watch for changes in any of the resolved files.
And for Server I recommend you webpack-dev-server
npm i webpack-dev-server
can be used to quickly develop an application
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000
}
};
And add it to your npm script
"scripts": {
"watch": "webpack --watch",
"start": "webpack-dev-server --hot --open",
}
Now we can run npm start from the command line and we will see our browser automatically loading up our page. If you now change any of the source files and save them, the web server will automatically reload after the code has been compiled.
Advise: you must add html file in dist or plugins for webpack HtmlWebpackPlugin

Webpack css-loader is not importing CSS

I have Server rendered my create-react-app by reading this tutorial.
And now, I cannot import CSS files in .js files!
Tried using style-loader, css-loader, extract-text-webpack-plugin, mini-css-extract-plugin, tried tweaking webpack configuration, but nothing helped.
NO StackOverflow answer helped. So this question. 😅
This is my package.json:
{
...
"scripts": {
"dev:build-server": "NODE_ENV=development webpack --config webpack.server.js --mode=development -w",
"dev:start": "nodemon ./server-build/index.js",
"dev": "npm-run-all --parallel build dev:*",
"start": "serve --single ./build",
"client": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"now-build": "react-scripts build && mv build dist",
"deploy": "npm run build && now ./build -A ../now.json --public --name=kumarabhirup"
},
...
}
This is webpack.server.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: './server/index.js',
target: 'node',
externals: [nodeExternals()],
output: {
path: path.resolve('server-build'),
filename: 'index.js'
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader'
},
{
test: /\.css$/,
// use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader'] NOT WORKED
use: ExtractTextPlugin.extract('style-loader', 'css-loader') // NOT WORKING
},
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
}
]
},
plugins: [
new webpack.EnvironmentPlugin({...process.env}),
new ExtractTextPlugin('[name].css') // TRIED THIS TOO
// new MiniCssExtractPlugin({ TRIED THIS
// filename: 'style.css',
// })
]
};
Error it throws at me when I, import 'react-circular-progressbar/dist/styles.css',
/Users/iqubex/Sites/kumarabhirup/kumarabhirup/node_modules/react-circular-progressbar/dist/styles.css:7
.CircularProgressbar {
^
SyntaxError: Unexpected token .
at new Script (vm.js:83:7)
at createScript (vm.js:267:10)
at Object.runInThisContext (vm.js:319:10)
at Module._compile (internal/modules/cjs/loader.js:686:28)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:734:10)
at Module.load (internal/modules/cjs/loader.js:620:32)
at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
at Function.Module._load (internal/modules/cjs/loader.js:552:3)
at Module.require (internal/modules/cjs/loader.js:659:17)
at require (internal/modules/cjs/helpers.js:22:18)
[nodemon] app crashed - waiting for file changes before starting...
All that I expect is the working of imported CSS files. Please help 🙌🏻
#gopigorantala is right.
Change the loader to one of these, it should work:
use: ['style-loader', 'css-loader']
or
use: [MiniCssExtractPlugin.loader, 'css-loader']
You probably won't need to use ExtractTextPlugin. Just use MiniCssExtractPlugin. It'll work.
The style-loader loads the styles into DOM with <style> at runtime, and MiniCssExtractPlugin extract them to a separate file. So you don't need to use both of them.

How to put React in production mode?

I tried using the solution from here but the icon is still read indicating dev mode.
Here is my current file with updates from the answer below:
const path = require('path');
const SRC_DIR = path.join(__dirname, '/client-react/src');
const DIST_DIR = path.join(__dirname, '/client-react/dist');
const webpack = require('webpack')
module.exports = {
entry: `${SRC_DIR}/index.jsx`,
output: {
filename: 'bundle.js',
path: DIST_DIR
},
plugins: [
new webpack.DefinePlugin({'process.env': {NODE_ENV: JSON.stringify('production')} })
],
module: {
loaders: [
{
test: /\.jsx?/,
include: SRC_DIR,
loader: 'babel-loader',
query: {
plugins: ["transform-object-rest-spread", "transform-class-properties"],
presets: ['react', 'es2015']
}
}
]
}
};
If you use Webpack 4, you don't need to change webpack.config.js. It remains the same in both development and production modes.
The only thing needed is in your package.json:
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
Having this, to create a development bundle:
npm run dev
Production bundle:
npm run build
When you want to build your app in production mode, you should use webpack production shortcut. Like this:
webpack -p
This will enable webpack optimize options to minify your JS. See more detailed explanation of webpack flags on this SO answer.
Webpack plugins need to be put under the plugins key in module.exports.
https://webpack.github.io/docs/using-plugins.html#built-in-plugins
Try this:
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify('production') }
}),
]
}
Had the same error so to fix it I did this:
package.json
"scripts": {
"build": "NODE_ENV=production webpack --progress --colors",
"start": "NODE_ENV=development webpack-dev-server --progress --colors"
}
webpack.config.js
const env = process.env.NODE_ENV
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env)
})
]
}
It should work for sure.
Here I have some configuration that you can try to optimize your build.
This worked for me: run npm run build followed by npm install -g serve and serve -s build

Categories

Resources