bundle.js missing from webpack build when using webpack-dev-server - javascript

I looked at similar but couldnt find a concerete answer that resolved my issue. I can't find the bundle.js file even though I am specifying where it should be outputted and everything works in the browser. I understand that the webpack-dev server is loading the files from memory and nothing is being written to disk, how I can get the file to be built and added to the dir specified in the output property in the config file?
Here is my package.json:
{
"name": "redux-simple-starter",
"version": "1.0.0",
"description": "Simple starter package for Redux with React and Babel support",
"main": "index.js",
"repository": "git#github.com:StephenGrider/ReduxSimpleStarter.git",
"scripts": {
"start": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js -- content-base build"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.2.1",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.1.18",
"babel-preset-react": "^6.1.18",
"react-hot-loader": "^1.3.0",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.14.0"
},
"dependencies": {
"babel-preset-stage-1": "^6.1.18",
"react": "^0.14.3",
"react-dom": "^0.14.3",
"react-redux": "^4.0.0",
"redux": "^3.0.4"
}
}
webpack config:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./src/index.js'
],
output: {
path: path.join(__dirname, 'assets'),
publicPath: '/',
filename: 'bundle.js'
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel'
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
contentBase: './'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};

When using the dev server, the output is placed on it. So you won't actually see it amongst your files. From your index.html file you will want to load it in from the server.
For example, for my app I load in dev server, my vendor files, and then my own code.
<script src="http://localhost:8080/webpack-dev-server.js"></script>
<script src="http://localhost:8080/build/vendor.js"></script>
<script src="http://localhost:8080/build/app.js"></script>
And here is the relevant portion of my webpack config. There is some unnecessary legacy bits from when I was also loading it in from a static build bundle.
app: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080',
'./client/index.js'
]
},
output: {
path: __dirname + '/client/build',
publicPath: '/build/',
filename: '[name].js',
pathinfo: true
},

This Webpack plugin forces the server to write the bundle to disk.
Although I agree with Austin and lux, if you need to have the file in disk, call webpack directly.

Include below script in the webpack.config.js file
devServer: {
writeToDisk: true
}

You can also tell webpack to watch using a flag in the config. This will generate the bundle file
module.exports = {
watch: true,
};

Replace your scripts object of package.json file with the following one:
"scripts": {
"start": "npm run build",
"build": "webpack -p && ./node_modules/webpack-dev-server/bin/webpack-dev-server.js -- content-base build"
},
Then, run $ npm start

Related

Webpack does not generate source maps

I'm new to webpack and am trying to make a webpack configuration that generates source maps so I can debug my JS and JSX code in the browser.
The build is actually successful so far, except that no source maps are generated. I've been researching for a long time and tried many solutions, including several ones from StackOverflow. But nothing works for me.
Below I am posting my current files in the hope that someone can help me. Thanks in advance for helping.
Root directory after build:
- webpack.config.js
- package.json
- package-lock.json
- node_modules
- dist
|- bundle.js
|- bundle.js.map
|- index.html
|- main.min.js
|- main.min.js.map
|- node_modules
- src
|- index.html
|- index.js
|- helper.jsx //My own jsx file
What my webpack app looks like in the browser:
webpack.config.js:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports =
{
entry: path.join(__dirname, "src", "index.js"),
mode: 'development',
devtool: 'source-map',
output:
{
path: path.resolve(__dirname, "dist"),
filename: "[name].min.js"
},
module:
{
rules:
[
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use:
{
loader: "babel-loader",
options:
{
presets:
[
'#babel/preset-env',
'#babel/preset-react'
]
}
}
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.(png|jp(e*)g|gif)$/,
use: ['file-loader'],
},
]
},
plugins:
[
new HtmlWebpackPlugin
(
{
template: path.join(__dirname, "src", "index.html"),
hash: true
}
),
],
}
package.json:
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"dev": "webpack serve"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"#babel/core": "^7.20.12",
"#babel/preset-env": "^7.20.2",
"#babel/preset-react": "^7.18.6",
"babel-loader": "^9.1.2",
"html-webpack-plugin": "^5.5.0",
"source-map-loader": "^4.0.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}
}

Webpack production version of website points to the wrong directories

I have two npm commands "build": "webpack --mode production" and "start": "webpack-dev-server --mode development --open". When I run the start command the web application runs as intended with all the CSS and javascript being transpiled correctly.
However when I run build the fils are generated as intended and when the main HTML file is opened the href and src do not point to the correct directories.
I looked at my webpack.config.js and it appears to be working as intended which leads me to a bit of head-scratching. Changing the HTML template causes the development version to break and have the production version work as intended. The intention is for both development and production version to work as intended.
For reference here is my directory structure:
root
|-.vscode
|-dist
| |-css
| |-img
| |-js
| |- output location for bundle.js index.html main.css
|-node.modules
|-src
|-css
| |-scss
|-js
| |-JSON
| |-models
| |-view
| |-app.js
|-index.html
|-.babelrc
|-package-lock.json
|-package.json
|-webpack.config.js
Webpack config file
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const babelLoader = require("babel-loader");
module.exports = {
entry: [
"babel-polyfill","./src/js/app.js"
],
output: {
path: path.resolve(__dirname, "dist/js"),
filename: "bundle.js",
},
devServer: {
contentBase: "./dist"
},
plugins: [
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
filename:"index.html",
template:"./src/index.html"
})
],
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"]
}
}
},
{
test: /\.scss$/,
use: [{
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader",
options: {
sourceMap: true,
modules: true,
localIdentName: "[local]"
}
},
"sass-loader"
]
}
]
}
}
and package.json
{
"name": "tempName",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development --open"
},
"author": "Fake Name",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.7.2",
"#babel/preset-env": "^7.7.1",
"babel-loader": "^8.0.6",
"chart.js": "^2.9.3",
"css-loader": "^2.1.1",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"gulp-babel": "^8.0.0",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.7.0",
"node-sass": "^4.13.0",
"sass-loader": "^7.3.1",
"sortablejs": "^1.10.1",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"
},
"dependencies": {
"axios": "^0.19.0",
"babel-polyfill": "^6.26.0",
"pokedex-promise-v2": "^3.2.0"
}
}
How do I specify the href(s) and src(s) in the HTML document to link to the CSS and javascript since they are added during the build script and are not in the HTML template?
Try these things:
1) instead of setting contentBase to dev-server try to set 'publicPath: '/'
2) set 'output.publicPath' to '/' also
3) if previous doesn't work, HtmlWepbpackPlugin has base option to add prefix for loaded scripts. but i strongly recommend to handle it with public path.
PS: fix your prod build, and only when fix webpack-dev-server. it will be easier

Javascript bundled with webpack not working

So basicaly I can't get any of my javascript to work after linking bundle.js onto my index.html. Every function is undefined even tho bundle.js is being loaded and I can access it via source code in dev tools. However if I link my javascript file "app.js" directly everything works as intended. I figured there will most likely be a problem with my webpack setup since this is my first time setting it up. I'll be glad for any other tips regarding this webpack.config. Thanks in advance :)
Here is my package.json:
{
"name": "name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"dev": "webpack --mode development",
"devs": "webpack-dev-server --mode development"
},
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^1.0.0",
"extract-loader": "^3.0.0",
"file-loader": "^2.0.0",
"font-awesome": "^4.7.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.4.4",
"node-sass": "^4.9.4",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.23.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
}
}
webpack.config.js:
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: {
main: ["./src/index.js"]
},
output: {
filename: "scripts/bundle.js",
path: path.resolve(__dirname, "./dist")
},
module: {
rules: [
{
test: /\.html$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].html"
}
},
{
loader: "extract-loader"
},
{
loader: "html-loader",
options: {
attrs: ["img:src"]
}
}
]
},
{
test: /\.sass$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
},
{
test: /\.(jpg|gif|png)$/,
use: [
{
loader: "file-loader",
options: {
name: "images/[name].[ext]"
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "styles/[name].css",
chunkFilename: "[id].css"
})
],
watch: true,
};
main webpack entry index.js:
require('./scripts/app.js');
require('./styles/sass/app.sass');
require("./index.html");
index.html script link:
<script src="./scripts/app.js"></script>
EDIT Problem is definitely within bundle.js that is being generated. If I copy the function at the begining of the bundle.js everything works as intended. Here is bundle.js code in fiddle:
https://jsfiddle.net/ustqkg7v/
If I copy the function from app.js at the beginning of the bundle.js, everything works as intented. I think there might be a problem with scope but I am not sure.
EDIT 2 I've setup smaller project with same folder structure, files, etc. Exactly the same issue. Here is link:
https://www.dropbox.com/s/9f5pf6y4fbb60dw/webpack4-test.rar?dl=0
The issue may be also because of this path: path.resolve(__dirname, "./dist").I am assuming the webpack.config.js is at the root level of the project so I think it has to be path: path.resolve(__dirname, "dist")
Then in html it need to be referred from dist folder
<script src="./dist/app.js"></script>
Before this check if app.js is getting generated in dist folder

why webpack can't find loader

Here's my pacjage.json:
{
"name": "redux-todo",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "webpack-dev-server"
},
"devDependencies": {
"babel": "^6.5.2",
"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.13.2",
"babel-preset-react": "^6.11.1",
"webpack": "^1.13.2"
},
"dependencies": {
"react": "^15.3.1",
"react-dom": "^15.3.1",
"react-redux": "^4.4.5",
"redux": "^3.5.2"
}
}
webpack.config.js:
var path = require('path');
module.exports = {
entry: './index.js',
output: {
path: './',
filename: 'app.js'
},
devServer: {
inline: true,
port: 3334
},
resolveLoader: { root: path.join(__dirname, "node_modules") },
module: {
loaders: [
{
test: /\.js$/,
exclude: '/node_modules',
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}
]
}
};
and I have following project directory structure:
├── actions.js
├── components
├── containers
├── index.js
├── node_modules
├── package.json
├── reducers.js
├── test.js
└── webpack.config.js
the absolute path to project dir is /home/dmitriy/WebstormProjects/Redux-todo
so why when I run npm start it crashes with error:
ERROR in (webpack)/~/process/browser.js
Module build failed: Error: Couldn't find preset "es2015" relative to directory "/usr/local/lib/node_modules/webpack/node_modules/process"
what's this /usr/local/lib/node_modules/webpack/node_modules/process path and why it says that it searches relative to it?
Googling this error I found that
IMPORTANT: The loaders here are resolved relative to the resource which they are applied to. This means they are not resolved relative the the configuration file. If you have loaders installed from npm and your node_modules folder is not in a parent folder of all source files, webpack cannot find the loader. You need to add the node_modules folder as absolute path to the resolveLoader.root option. (resolveLoader: { root: path.join(__dirname, "node_modules") })
should fix it, but as you can see I have it in my config and still seeing this error.
I'm on ubuntu 16.04 LTS, nodejs version is 4.2.6, npm 3.5.2
You are only excluding /node_modules as absolute path:
exclude: '/node_modules'
If you want to recursively exclude all node_modules try using:
exclude: /node_modules/
The difference is subtle but the former is using a string with an absolute path to the root node_modules and the latter a regular expression that matches any path with node_modules.
This should work without the resolveLoader configuration. So you can remove this field:
resolveLoader: { root: path.join(__dirname, "node_modules") },
actually I removed node_modules, tweaked package.json a little bit:
{
"name": "redux-todo",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "webpack-dev-server"
},
"dependencies": {
"babel": "^6.5.2",
"react": "^15.3.1",
"react-dom": "^15.3.1",
"react-redux": "^4.4.5",
"redux": "^3.5.2"
},
"devDependencies": {
"babel-core": "^6.13.2",
"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.13.2",
"babel-preset-react": "^6.11.1",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.14.1"
}
}
aaand it worked. Not sure why. Here's how webpack config looks like now:
var path = require('path');
module.exports = {
entry: './index.js',
output: {
path: './',
filename: 'app.js'
},
devServer: {
inline: true,
port: 3334
},
module: {
loaders: [
{
test: /\.js$/,
exclude: '/node_modules',
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}
]
}
};
I have no clue what was that about ¯_(ツ)_/¯
For my project the loader is configured like this:
{
test: /\.js$/,
exclude: '/node_modules',
loader: "babel-loader"
}
And the .babelrc file contains this:
{
"presets": ["es2015","react"]
}
Watching the first config of webpack that you have posted, I noticed the option resolveLoader: { root: path.join(__dirname, "node_modules") }. This option isn't needed if you have all loader on correct path (node_modules directory on project root).
Did you mean to use babel-loader? If so, and if there is no babel-loader folder in node_modules, then npm install babel-loader#7.1.1 --save-dev should fix the issue and generate that folder.

React Js - how to keep bundle.min.js small?

I'm pretty new to React and javascript dev. I'm used to java build tools, so now using NPM i've got a new landscape of build tools to learn. I am just getting going into my project and I noticed that my minified, uglified bundle is still ~275kb and I'm wondering how this could scale to a large size app. My raw source code itself is only 34kb, but of course I have to pull in all those frameworks and whatnot.
So - how can I keep the size of my app small as my app grows? It's a bit hard for me to follow stuff I read online because many folks seem to be using Grunt, but i'm just using npm start and npm run build on the package below.
Should I be managing my requires() in different ways to prevent duplicate packaging? I'm not sure where to start...
Here's my package.json:
{
"name": "someapp",
"version": "0.0.1",
"description": "foo",
"repository": "",
"main": "js/app.js",
"dependencies": {
"classnames": "^2.1.3",
"flux": "^2.0.1",
"jquery": "^2.2.0",
"keymirror": "~0.1.0",
"object-assign": "^1.0.0",
"react": "^0.12.0"
},
"devDependencies": {
"browserify": "^6.2.0",
"envify": "^3.0.0",
"jest-cli": "^0.4.3",
"reactify": "^0.15.2",
"uglify-js": "~2.4.15",
"watchify": "^2.1.1"
},
"scripts": {
"start": "watchify -o js/bundle.js -v -d js/app.js",
"build": "browserify . -t [envify --NODE_ENV production] | uglifyjs -cm > js/bundle.min.js",
"test": "jest"
},
"author": "Some Guy",
"browserify": {
"transform": [
"reactify",
"envify"
]
},
"jest": {
"rootDir": "./js"
}
}
I was able to achieve pretty good results with Webpack. I wrote about this in Optimizing Webpack Prod Build for React + ES6 Apps
Here's my Webpack config:
var webpack = require('webpack');
var path = require('path');
var nodeEnv = process.env.NODE_ENV || 'development';
var isProd = nodeEnv === 'production';
module.exports = {
devtool: isProd ? 'cheap-module-source-map' : 'eval',
context: path.join(__dirname, './client'),
entry: {
jsx: './index.js',
html: './index.html',
vendor: ['react']
},
output: {
path: path.join(__dirname, './static'),
filename: 'bundle.js',
},
module: {
loaders: [
{
test: /\.html$/,
loader: 'file?name=[name].[ext]'
},
{
test: /\.css$/,
loaders: [
'style-loader',
'css-loader'
]
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loaders: [
'react-hot',
'babel-loader'
]
},
],
},
resolve: {
extensions: ['', '.js', '.jsx'],
root: [
path.resolve('./client')
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: false
}),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify(nodeEnv) }
})
],
devServer: {
contentBase: './client',
hot: true
}
};
Two key points to consider:
devtool: isProd ? 'cheap-module-source-map' : 'eval',
This one will output minimal sourcemaps, and will use external files for that, which is good for your final bundle size.
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: false
}),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify(nodeEnv) }
})
],
Uglify - well you probably know what it does. Coupled with the process.env setting will weed out quite a bit of dev code from React lib.
CommonsChunkPlugin will allow you to bundle libraries (or other chunks per your liking) to separate build files. This is particularly awesome as it allows you to set up different caching patterns for vendor libraries. E.g. you can cache those more aggressively than your business logic files.
Oh, and if you care to see my package.json that matches this webpack config:
"scripts": {
"start": "webpack-dev-server --history-api-fallback --hot --inline --progress --colors --port 3000",
"build": "NODE_ENV=production webpack --progress --colors"
},
"devDependencies": {
"babel-core": "^6.3.26",
"babel-loader": "^6.2.0",
"babel-plugin-transform-runtime": "^6.3.13",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"file-loader": "^0.8.4",
"webpack": "^1.12.2",
"webpack-dev-server": "^1.12.0",
"webpack-hot-middleware": "^2.2.0"
}
Edit: Tree shaking is a shiny new version expected in Webpack 2 (currently in beta). Coupled with the config above, it will be a killer feature that will minify your final bundle significantly.
Edit 2: Webpack 2 I modified an existing sample app to use Webpack 2 config. It resulted in additional 28% savings. See the project here:Webpack 2 sample config project

Categories

Resources