How come I am getting Cannot GET / in my browser? I think it is because my webpack-dev-server does not have a route to GET the bundled files.
devServer/server.js
import config from '../../webpack.config';
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import open from 'open';
// template! https://github.com/webpack/webpack-dev-server/blob/master/examples/node-api-simple/server.js
const compiler = webpack(config);
const server = new WebpackDevServer(compiler, {
contentBase: '../dist/',
stats: {
colors: true
}
});
server.listen(3000, '127.0.0.1' ,err => {
if (err) {
console.log(err);
} else {
console.log('Dev Server listening on port 3000!\n');
open("http://localhost:3000");
}
});
webpack.config.js
import webpack from "webpack";
export default {
entry: [
"./app/index"
],
devtool: "inline-source-map",
output: {
path: __dirname + "/app/dist/", // Note: Physical files are only output by the production build task `npm run build`.
publicPath: "/",
filename: "bundle.js"
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
],
module: {
rules: [
{ test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'react']
}
}}
]
}
};
Project structure
On successful build a folder dist will be created inside the app folder which currently is not there.
Once the folder is created you can try by directly hitting the file path
http://localhost:3000/app/dist/yourfile
You can access your page via localhost:3000
When you access this path webpack dev server is searching for an index.html file to serve (like any other webserver). It can not find an index.html file because you have no index.html file. The index.html file is served from the static directory, which you have defined via property contentBase: '../dist/',.
but as I see you have no directory named dist and you have no index.html in this directory.
Your script is served from the public path, that is / in your config, so you have to reference this in your index.html
Solution:
Create directory dist and put an index.html file there with the following content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="/bundle.js"></script>
</body>
</html>
For more information read here:
https://webpack.github.io/docs/webpack-dev-server.html
Related
I have a simple project with a few html files in root folder and a few javascript modules in scripts directory.
I want to start using webpack now because I want minification and to start using environments. Everything was working before I started using webpack.
I read documentation for Webpack 5 but could not find anything that solves my problem. So I came up with this webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: {
lib: "./scripts/lib.js"
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
devServer: {
contentBase: "./dist",
inline: true, //Enable watch and live reload
host: "localhost",
port: 8080,
stats: "errors-only",
https: false
},
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "index.html",
hash: true
})
],
module: {
rules: [
{
test: /\.html$/i,
loader: 'html-loader',
},
],
},
};
My index.html imports and uses module functions like this:
<script type="module">
import * as lib from "./scripts/lib.js";
window.lib = lib;
</script>
<body onload="lib.myFn()">
</body>
But after running this webpack (using webpack serve) I am getting "is not a function" or "module not found" errors.
How can I compile and run my existing project with webpack without making any changes in my directory structure and fix this error so I can start using functions in lib.js in my index.html? Thanks.
There is a simple task:
I want to try making a Google Chromecast receiver app (which is SPA). Google Chromecast SDK (cast SDK) requires their framework to be on external url. Also this framework creates global cast object.
What is the correct way of creating this webpack application?
The targets I want to achieve:
Build index.html with HtmlWebpackPlugin
Develop using import this framework (import cast from ???)
Avoid bundling it (probably using externals)?
Ensure cast object created by this js file is global (ProvidePlugin?)
Add <script src="http://cdn....js"></script> into HTML created by HtmlWebpackPlugin
For now I am trying to setup simple app, and I got stuck on last step - adding <script> tag to output html, but I'm sure that there are mistakes I've done on prev steps.
Could you help guiding me through this process?
My current webpack.config.js is:
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
scriptLoading: 'defer',
hash: true,
}) ,
new webpack.ProvidePlugin({
cast: path.resolve(path.join(__dirname, 'src/cast_receiver_framework'))
})
],
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
devServer: {
compress: false,
disableHostCheck: true
},
externalsType: 'script',
externals: {
cast_receiver_framework: ['//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js', 'cast']
}
}
To solve your last step you can use the template param of HtmlWebpackPlugin to customize your template.
By default HtmlWebpackPlugin will inject bundled modules at the end of the <body>.
Check the documentation if you need further customization.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Whatever else you might need -->
</head>
<body>
<div id="your-mount-point-id"></div>
<script src="http://cdn....js"></script>
</body>
</html>
webpack.config.js
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "path/to/index.html"),
scriptLoading: 'defer',
hash: true,
})
],
I have the following express application:
const express = require("express");
const app = express();
const server = require("http").Server(app);
const path = require("path");
const port = process.env.PORT || 5000;
app.use('/public', express.static(path.resolve(__dirname, "../public"))); // every file under public folder is referenced as /public
app.use('/resource', express.static(path.resolve(__dirname, "../dist"))); // every file under resource folder is referenced as /resource
server.listen(port, function() {
console.log("server is running on port", port);
});
On the front-end, in the public directory, I am placing all HTML and CSS files. I am giving one of the HTML files below as an example:
<head>
<title>Pllanet Home</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<script src="/resource/js/script1" defer></script>
<script src="/resource/js/script2" defer></script>
</head>
// body
All the JS files that each HTML file is using are placed in a ./dist folder. Each JS file has been built with Webpack and Babel with the following configuration:
const path = require('path');
const glob = require('glob');
module.exports = {
entry: Object.fromEntries(glob.sync(path.resolve(__dirname, 'src/js/*.js')).map((v) => [
path.basename(v, '.js'), v,
])),
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ["#babel/preset-env"],
plugins: [
[
"#babel/plugin-transform-runtime",
{
"useESModules": true
}
]
]
}
}
}
]
}
};
Unfortunately when I ran my app on localhost:5000. The built JS files have an error of:
Refused to execute script from 'http://localhost:5000/resource/js/main/flip_auto.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
If I don't use the JS files built with webpack, my app runs correctly. What is wrong with my application here?
I found what was the mistake. I was loading JS files from invalid directories, which produced the error.
I am new to webpack and currently trying to go through some demos. However it seems that my server cannot find the file referenced from index.html file.
I am using http-server, and this is the index.html page:
<html>
<head>
<title>Page title</title>
</head>
<body>
<div id="app"></div>
<script src="../build/js/bundle.js"></script>
</body>
</html>
...and my webpack.config.js file:
var path = require("path");
module.exports = {
context: path.resolve("src"),
entry: "./index.js",
output: {
path: path.resolve("build/js/"),
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}
]
},
resolve: {
extensions: [".js", ".es6"]
}
};
Currently I am trying to setup the following file structure:
build
js
bundle.js
src
js
App.js
index.js
public
index.html
After running webpack and starting the server I get a 404 error, stating that bundle.js could not be found.
I have a demo like this:
my webpack config:
module.exports = {
entry: './app.js',
output: {
filename: 'bundle.js',
path: './build',
publicPath: 'http://localhost:3000/'
},
module: {
rules: [{
test: /static\.html/,
use: 'file-loader'
}, {
test: /\.png/,
use: 'file-loader?name=[name].[ext]'
}, {
test: /\.css/,
use: 'file-loader?name=[name].[ext]'
}],
},
resolveLoader: {
modules: ['node_modules'],
}
}
this is my entry app.js:
import './static.html';
import './img.png';
import './index.css';
static.html:
<!DOCTYPE html>
<html>
<head>
<title>static</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="./index.css">
</head>
<body>
<img src="./img.png">
</body>
</html>
when i run npm run build, i got a build folder. I think the build/static.html should be
<img src="http://localhost:3000/img.png">
<link href="http://localhost:3000/index.css">
But, actually the build/static.html is the same as static.html. Both of the src of img and the href of link are not changed.
Any one knows why?
====
I have known the answer. Webpack publicPath just work for output file. So just the url in the bundle.js will be replaced.
The webpackHtmlPlugin will not resolve this problem, because this plugin will generate a html page with a script links to the output bundle.js that I don't need it.
To resolve this problem, I have wrote a custom loader to transform the html page output by the file-loader dynamicly.
The file-loader would not change the file. If you want a html file with the publicPath added, you should use html-webpack-plugin.