I am new to webpack. I am learning react and building environment for it using webpack.
I have webpack-config.js
var path = require('path');
module.exports = {
mode: 'production',
entry: './script.js',
output:
{
path: path.resolve(__dirname, 'src'),
filename: 'transpiled.js'
},
module:
{
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query:
{
presets: ['es2015','react']
}
}
]
}
}
and script.js
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello world</h1>
document.getElementByIdName('first')
);
and index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="first"></div>
<script src="transpiled.js"></script>
</body>
</html>
in Pakage.json file I have written
"scripts": {
"it": "webpack-dev-server --hot"
},
But when i run the npm with "npm run it", it shows me the error of
WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.
ERROR in multi -dev-derver/client?http://localhost:8080 webpack/hot/dev-server ./src
Module not found: Error : Cant resolve './src' in D:\React Js \LearnReact' #multi -dev-derver/client?http://localhost:8080 webpack/hot/dev-server ./src
i ?wdm?: failed to Compile.
Please help me i am really stuck and want to know the solution.
You need to add pass the --config option to webpack-dev-server:
webpack-dev-server --config path/to/webpack.config.js
Also set your mode to development in your base config, you can overwrite it later when you do a production build.
Also ensure that your ./script.js file is in the root of your project, i.e next to your package.json since this file path is relative to the npm script execution.
Based on this configuration --> path: path.resolve(__dirname, 'src') all your built assets will end up in a src folder in the root of your project, assuming that is where your webpack.config.js file is (this path is relative to your config file). The actual folder will only be generated in production, in development assets are stored in memory.
You might also want to set a publicPath:
output: {
...
publicPath: '/'
}
I would also recommend using the html-webpack-plugin since this can resolve the correct paths to your js file for you.
var HtmlWebpackPlugin = require('html-webpack-plugin');
...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // name of file that will be outputted to 'src' when built
template: // path to your html file relative to config
inject: true
})
]
Then you don't have to include the path to your script, so your html file would look like:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="first"></div>
</body>
</html>
Related
I try to build TypeScript code for html viewing, I have the following code:
console.log('hello world');
After building code with "yarn build", "node ./node_modules/webpack/bin/webpack --mode development"
run it with "node ./node_modules/webpack-dev-server/bin/webpack-dev-server --mode development "
Also html file generated by builder is included in src directory and webpackbundle.js is also there:
<!DOCTYPE html>
<html>
<head>
<title>Canvas demo</title>
<script defer src="webpackbundle.js"></script></head>
<body>
<script src="webpackbundle.js"></script>
<p id="clear">above</p>
</body>
</html>
But after running there is no expected output "hello world" on html, only "above" as stated as initial html, so it seems that app isn't viewed by running html
My webpack.config.js loks like:
var HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require("path");
module.exports = {
mode: "development",
devtool: "source-map",
entry: './game.tsx',
output: {
path : path.resolve(__dirname, 'src'),
filename: 'webpackbundle.js'
},
...
plugins: [new HtmlWebpackPlugin({
path : path.resolve(__dirname, 'src'),
template: "index.html",
hash: true, // This is useful for cache busting
filename: 'index.html'
})]
} //also have rules for typescript and resolve, port specification
In src webpackbundle.js.map is generated and webpackbundle.js has corresponding console.log('hello world') code, but there is no related output in html
Could anybody advise on how to make code output visible in html?
My website doesn't load because the request for bundle.js instead returns the index.html file.
This project is from a few years ago and at the time it worked fine, but I'm trying to get it up and running again and I'm not sure why this is happening now. If anyone can help, I'd really appreciate it!
File structure:
- src
- app
- db
- public
- assets (folder)
- styles (folder)
- index.html
- server
- auth (folder)
- routers (folder)
- server.js
- webpack.config.js
webpack.config.js:
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: path.resolve(__dirname, 'src/app', 'client.jsx'),
output: {
path: path.resolve(__dirname, 'src/public/build'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
include: path.resolve(__dirname, 'src/app'),
loader: 'babel-loader'
}
]
},
devtool: 'source-map'
};
From index.html:
<body>
<div id="app"></div>
<!-- load the app scripts -->
<script src="/build/bundle.js"></script>
</body>
From server.js:
app.use(express.static(path.resolve(__dirname, '../public')));
app.use('*', function (request, response){
response.sendFile(path.resolve(__dirname, '../public', 'index.html'))
})
From package.json:
"scripts": {
"start": "webpack --watch | nodemon --ignore node_modules ./src/server/server.js --exec babel-node"
},
From .babaelrc:
{
"presets": [
"#babel/preset-env",
"#babel/preset-react",
"airbnb"
],
"plugins": [
["#babel/plugin-proposal-decorators", { "legacy": true }],
["#babel/plugin-proposal-class-properties", { "loose": true }],
"react-html-attrs",
"transform-class-properties",
]
}
[reputation is too low to comment]
Everything looks kosher, so I agree with #eol the first step is to actually transpile and confirm the build is working as intended.
As a semi-related aside, I believe you should move the path resolution in the main request handler to be a constant that is only invoked and resolved once... probably a minimal gain, but as it stands every request has the same path resolved.
const indexFile = path.resolve(__dirname, '../public', 'index.html');
app.use('*', function (request, response) { response.sendFile(indexFile); });
(This isn't relevant for the first handler, as the resolution will only occur once when the static method is invoked.)
Regarding the start script: I don't think you want to be piping the output from the webpack --watch command to nodemon? You probably want to push the webpack command to run in the background and then execute nodemon. I don't even think webpack watch will actually exit so nodemon would never be called?
Try webpack --watch & nodemon ....
I don't see anything that jumps out as to why the build wouldn't be working besides that... does it compile if you just run webpack in your terminal in the root directory?
I have installed plotly using npm i plotly.js
Added the line import 'plotly.js/dist/plotly' to my plotly import file
Then in webpack followed the instructions here to bundle the files client side.
Added in a custom js file to test plotly
Then added in the plotly scripts to my html page with the package coming first then my custom js.
However I get the error message ReferenceError: Plotly is not defined.
To test I was using the javascript code from this example. I can get it working when I save the file locally found on the plotly site here but not with webpack.
Is there something I am missing or doing wrong? My other packages seem to work fine and I can see plotly.js has successfully been added into the relvent folder client side.
webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: {
uibundles: path.resolve(__dirname, 'frontend.js'),
plotly: path.resolve(__dirname, 'plotlyimport.js'),
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'public/js')
},
plugins: [new MiniCssExtractPlugin({
filename: '../css/[name].css',
})],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.js$/,
loader: 'ify-loader'
},
]
}
};
You probably need to use webpack resolve (here) to add the details
Could you try this:
resolve: {
modules: ['node_modules'],
extensions: ['.js']
},
It seems like you need to use webpack externals to solve this issue.
webpack externals : Prevent bundling of certain imported packages and instead retrieve these external dependencies at runtime.
For example, to include plotly from a CDN instead of bundling it:
index.html
<script src="../plotly.js"></script>
webpack.config.js
module.exports = {
//...
externals: {
plotly: 'plotly'
}
};
This leaves any dependent modules unchanged, i.e. the code shown below will still work:
var Plotly = require('plotly.js');
..
..
Plotly.newPlot('myDiv', data, layout, config );
Refer to webpack externals for more details.
I'm trying to create a react app that has a server.coffee file already created for me. I set up babel and webpack and have created my index.js and app.js files. I've added script tag for bundle.js on my index.html. I keep getting error message when I run server on localhost : Failed to load resource: the server responded with a status of 404 (Not Found) for bundle.js:1. I see the file in my directory locally. What am I missing?
HTML File:
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<link href="/static/base.css" rel="stylesheet">
<script defer src="./bundle.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
my webpack:
module.exports = {
entry: ['#babel/polyfill','./client/index.js'],
mode: 'development',
output: {
path: __dirname,
filename: './public/bundle.js'
},
devtool: 'source-maps',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
}
my .babelrc:
{
"presets": ["#babel/preset-react", "#babel/preset-env"]
}
My directory structure:
client
|-index.js
|-App.js
public
|-bundle.js
|-index.html
.babelrc
package.json
server.coffee
webpack.config.js
This is the script I'm running:
"scripts": {
"start": "coffee server.coffee",
"start-dev": "webpack -w & coffee server.coffee"
}
Finally this is the app.get in my server.coffee file:
# Default public
app.get '/', (req, res) ->
res.sendFile __dirname + '/public/index.html'
Again this is the error I'm getting.
GET http://localhost:3000/bundle.js net::ERR_ABORTED 404 (Not Found)
No compile errors or anything on the terminal. Only console errors. Any help is appreciated! I know how to do the rest of the project but it's impossible without getting React running.
You need to use express.static() before your app.get() route.
app.use(express.static('public'))
Or in Coffeescript
app.use express.static 'public'
I have the following webpack.config.js file:
'use strict';
let path = require('path');
let webpack = require('webpack');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: [
'./index.js'
],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
devtool: 'inline-source-map',
watch: true,
module: {
rules: [
{
test: /\.jsx?$/,
use: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: [ 'style-loader', 'css-loader?modules', ],
publicPath: '/dist'
})
},
{
test: /\.ejs$/,
use: 'ejs-compiled-loader'
}
],
},
plugins: [
new ExtractTextPlugin({
filename: 'styles.css'
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
minify: {
collapseWhitespace: true
},
hash: true,
template: 'ejs-render-loader!./views/index.ejs'
}),
]
};
When trying to load an ejs file that contains <% somefile %> the file cannot be found.. this is the error I receive:
Child html-webpack-plugin for "index.html":
Asset Size Chunks Chunk Names
index.html 26.2 kB 0
chunk {0} index.html 554 bytes [entry]
[./node_modules/ejs-render-loader/index.js!./views/index.ejs] ./~/ejs-render-loader!./views/index.ejs 554 bytes {0} [built] [failed] [1 error]
ERROR in ./~/ejs-render-loader!./views/index.ejs
Module build failed: Error: ENOENT: no such file or directory, open 'head.ejs'
at Object.fs.openSync (fs.js:584:18)
at fs.readFileSync (fs.js:491:33)
at Object.exports.parse (/var/www/rio-olympics-3/monitor/node_modules/ejs-compiled-loader/node_modules/ejs/lib/ejs.js:168:19)
at Object.exports.compile (/var/www/rio-olympics-3/monitor/node_modules/ejs-compiled-loader/node_modules/ejs/lib/ejs.js:245:15)
at Object.module.exports (/var/www/rio-olympics-3/monitor/node_modules/ejs-compiled-loader/index.js:7:22)
webpack: Failed to compile.
I have tried many file path formats, and none of them worked, here is my ejs file with my head.ejs in the same folder:
<!DOCTYPE html>
<html lang="en">
<% include head %>
<body>
<div id="navbar-app"></div>
<p> Welcome, more coming soon! </p>
</body>
<!-- insert component scripts below here -->
<script src="dist/js/NavBarMain.js"></script>
</html>
You have two different loaders configured for the index.ejs, which results in a clash.
A general rule for all .ejs:
{
test: /\.ejs$/,
use: 'ejs-compiled-loader'
}
An inline rule for the template in html-webpack-plugin:
template: 'ejs-render-loader!./views/index.ejs'
If you only want to use the inline loader you can add a leading !, so webpack won't apply other loaders:
template: '!ejs-render-loader!./views/index.ejs'
The above fixes your problem, but it is a little questionable why you have two different ejs loaders. To be honest I'm not fully aware of the differences in the loaders since both point to the same GitHub repository, although it seems to me like ejs-render-loader is just an earlier version. They actually handle the includes differently, that's why you get the error.
From the example in Usage of ejs-compiled-loader:
// Child Templates
// path is relative to where webpack is being run
<%- include templates/child -%>
That means if you want to use the ejs-compiled-loader for all .ejs you need to change the include to:
<% include views/head %>
And you can get rid of the inline loader in the html-webpack-plugin:
template: './views/index.ejs'
It's up to you whether you want to change this, I would just try to avoid loader conflicts and I don't think ejs-render-loader will be updated anymore.
In fact there is a v2.2.0 of ejs-compiled-loader which went back to the other include behaviour, relative to the current file, which is definitively more intuitive. You can install it with:
npm install --save-dev ejs-compiled-loader#2.2.0