webpack-dev-server does not reload and build automatically - configuration issue - javascript

I am using in my project:
"webpack": "2.2.1",
"webpack-dev-server": "2.4.2"
and I need to build an application when a file change using webpack-dev-server live reloading.
In my package.json I have this setup:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --hot --inline"
},
Currently I am able to build the application manually by running:
webpack and I am able to initialize the developer server using npm start.
The problem I am facing is that after npm start and local server runs, if I make some changes in JS files the application is NOT being rebuilded and page is not refreshed automatically. Currently I need to rerun webpack manually all the time in console.
I receive no errors in console, so I suppose is a wrong configuration issue.
Could you please point me out what is wrong in my settings?
// file: webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'app.bundle.js',
},
devServer: {
inline: true,
port: 8080
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
}
};

webpack-dev-server serves the files from memory.
From readme:
It uses webpack-dev-middleware under the hood, which provides fast in-memory access to the webpack assets.
So it does not write any file to disk and it also works without the files being present on your file system. When you delete the build directory and start the dev server without running webpack before, it should still work. If it doesn't, you don't hit the paths that are served from the dev server and instead are using the files from the file system.
The index.html you're using is probably outside the build directory and therefore you include the bundle like this:
<script src="build/app.bundle.js"></script>
You're requesting /build/app.bundle.js on the server, but webpack-dev-server will only serve /app.bundle.js (because that's the filename you configured). To solve this issue you can configure output.publicPath:
output: {
path: path.resolve(__dirname, 'build'),
filename: 'app.bundle.js',
publicPath: '/build/'
},
This will affect loaders that include assets. If you don't want that, you can set devServer.publicPath instead, but it's recommended to keep them the same.

Related

How could I save webpack-dev-server changes?

I'm using Xampp for my PHP developing.
Beside, I write codes in javascript in MVC architecture. When I run "dev": "webpack --mode development" in NPM, that's all ok and I see changes in bundle.js . But when I run "start": "webpack-dev-server" and I go to localhost:8080/js/bundle.js, I see changes, but in real, it is not saved. Because I go to my virtual host and there is no change!
How could I save changes exactly? Why is this happening?
This is my webpack config:
module.exports = {
entry: ["babel-polyfill","./resources/assets/js/hadi/index.js"],
output: {
path: path.join( __dirname, 'public/js'),
publicPath: '/js/',
filename: 'bundle.js'
},
devServer: {
contentBase: path.join(__dirname, 'public'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use:{
loader: "babel-loader"
}
}
]
}
};
The dev server of webpack is not meant to save anything, it is just a development server with live reloading, hot-modules and many other features.
When you run webpack command (like a build) it actually creates the output files, your javascript bundle and your static assets are copied to your dist folder, depending on your configuration.
The production bundle is much lighter in size so it can be deployed, and the dev server just stores a temporal bundle on memory while it is running.

Relative references must start with either "/", "./", or "../"

I am newbie to lit-element, and when use import to include the library, I am getting error as:
Uncaught TypeError: Failed to resolve module specifier "lit-element".
Relative references must start with either "/", "./", or "../".
Please provide any alternatives/solutions.
import { LitElement, html } from 'lit-element';
class MyElement extends LitElement {
render(){
return html`
<div>
<p>A paragraph</p>
</div>
`;
}
}
customElements.define('my-element', MyElement);
This doesn't work because js imports must reference a specific file with either a relative path or an absolute path, assuming your project structure is something like the following:
/node_modules
/lit-element
/other-library
/src
/components
my-element.js
index.html
From my-element.js, your import would be
import {LitElement, html} from '../../node_modules/lit-element/lit-element.js'
However, since this kind of configuration is confusing and you'll probably end up setting a build script sometime too, the recommendation would be to keep your imports as they are right now and use a dev server that remaps your imports to node_modules like open-wc's web server
Update (Feb. 2021): The web server mentioned on this question has gone through a few iterations and improvements. The current package is #web/dev-server
As you probably know, this type of import is known as 'bare import':
import { LitElement, html } from 'lit-element';
And the error happens because web browsers cannot resolve bare imports by themselves.
I don't know what webserver are you using for developing, but a good way of avoid this type of warnings is choose one that could manage this type of imports, for example web-dev-server
There are other approaches, using, for example tools like Webpack, Polymer-cli, Open Web Components, etc, as this article explains, but, IMO, the web-dev-server option is a very good one for start.
I tried webpack for this issue and that works fine for me.
Here is how I set up webpack on my node javascript project.
First, you need to install the following packages on your project
npm install --save-dev webpack
npm install --save-dev html-webpack-plugin
npm install --save-dev css-loader
npm install --save-dev style-loader
Then, you have to create webpack.config.cjs on your project root and paste the following code into it. (please change file paths as your file structure)
const path = require('path');
const HtmlWebpack = require('html-webpack-plugin');
module.exports = {
entry: './src/app.js',
mode: 'development',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
},
plugins:[
new HtmlWebpack({
template:path.resolve(__dirname,'./src/template/index.html')
})
],
module:{
rules:[
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: "asset/resource"
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
]
},
devServer:{
port:8080,
hot: true,
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
client: {
progress: true,
},
}
}
then add this line to your package.json file
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server --open",
},
now open a terminal on your project root and run npm run dev on it.
You can serve bare module imports with polimer-cli.
a. install it: npm install --save-dev polymer-cli
b. Create polymer.json in your project with roughly contens:
{
"entrypoint": "index.html",
"shell": "app.js",
"npm": true
}
c. do polymer serve

Why does Webpack 2 output only one of my images?

I'm still fairly new to webpack 2 but I've got most of my configurations working so far. The only thing I'm having some difficulty understanding is that when I run "npm run build" to bundle my files into my "dist" folder I noticed that only 1 of my images are being bundled. I'm using 'file-loader'. FYI all my images still show on my dev-server when I run it and appear under the public paths I assigned. It's only my local output that's not displaying all the images. Anyone know what's going on?
My Folder Structure
webpack.config.js
module.exports = {
mode: "development",
entry: {
app: "app"
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].bundle.js",
publicPath: "/"
},
devServer: {
publicPath: '/',
port: 3000
},
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
publicPath: 'images/'
}
}
]
}
]
}
}
As you can see in my folder structure, it always builds with only one of my images being outputted. It's not a major issue (I don't think) since all the images still work when I run the app, but I would appreciate it if anyone could help me understand why only one image is outputting to my local 'dist'. Thank you.
Webpack only writes images to disk that you require. This is one of the benefits of Webpack, it only includes assets that your application needs, so Webpack will guarantee those images exist when you deploy.
To add more images to your output, require them either from your Javascript or CSS with url()s
Note that if you're using the dev server, Webpack doesn't write anything to disk, and keeps all compiled assets in memory.

Compile/transpile code while developing React app

I am developing an app in React.
Until now I have just included
<script src='//unpkg.com/react#15/dist/react.min.js'>
<script src='//unpkg.com/react-dom#15/dist/react-dom.min.js'>
<script src='//unpkg.com/babel-standalone#6/babel.min.js'>
and then I neither had to use
import React from 'react';
import ReactDOM from 'react-dom';
since everything was loaded nor had to compile anything since babel compiled it in real-time.
However, when I want to include third-party libraries installed with npm, it seems I have to use import. For instance, if I install react-dates with npm-install react-dates --save and want to include it with
import { DateRangePicker, SingleDatePicker, DayPickerRangeController } from 'react-dates';
I get the error
Uncaught ReferenceError: require is not defined
I guess it's because I don't use RequireJS, Webpack, Gulp or anything.
What is the preferred way to be able to include components while developing, so I don't have to compile my code everytime I did a small change?
You can use webpack to configure your code, and run it in watch mode or use
webpack-dev-server during development so, that will allow you to compile your code automatically any time you do a small change
Your webpack.config.js should look something like
var debug=process.env.NODE_ENV !== "production";
var path=require("path");
var webpack=require("webpack");
module.exports = {
context: path.join(__dirname, "src"),
devtool: debug ? "inline-sourcemap" : null,
entry: "./js/index.js",
module: {
rules: [{
test: /\.jsx?$/,
exclude: [/node_modules/],
use: [{
loader: "babel-loader",
options: {presets: ["stage-0","es2015","react"]}
}]
}]
},
output: {
path: __dirname + "/src",
filename: "bundle.js"
},
plugins: debug? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({mangle: false, sourcemap: false})
]
}
And in your package.json, you can define scripts
"scripts": {
"start": "webpack-dev-server --content-base src",
"build": "webpack --watch"
}
If you run a npm run build command webpack will start in watch mode and you won't need to recompile your code again and again.
or you can run npm start for using webpack-dev-server in development mode.
See how to set up webpack here

React + Webpack HMR is refreshing the page (not hot loading)

I'm having a bit of trouble getting the react-hot webpack loader to work correctly.
When I load the page I get the following as I would expect:
[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
But when I save a change the page automatically hard refreshes the browser (rather than a HMR replacement).
//webpack.config.js
{
entry: {
client: 'webpack-dev-server/client?http://localhost:8786', // WebpackDevServer host and port
app: "./HelloWorld.tsx"
},
devtool: process.env.WEBPACK_DEVTOOL || 'cheap-module-source-map',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].entry.js'
},
module: {
loaders: [
{
test: /\.ts(x?)$/,
loaders: ['react-hot', 'babel-loader?cacheDirectory=true,presets[]=es2015,presets[]=react', 'ts-loader']
}
]
},
devServer: {
contentBase: "./dist",
port:8786
},
plugins: [
new webpack.NoErrorsPlugin()
]
}
command: webpack-dev-server --hot --inline
on an interesting sidenote if I use babel-preset-react-hmre everything works as expected. (However I don't really want to use this as it seems less supported than the proper react-hot loader).
I just ran into this problem. A couple things:
To help debug your particular issue, try enabling "Preserve log" (in Chrome dev tools). This will persist console logs across page refreshes, so you'll at least be able to see any messages that webpack-dev-server is logging before it triggers a refresh.
In my case webpack-dev-server was refreshing because I had not opted into HMR in my entry js file. Adding the following line to the file solved the issue:
// Opt-in to Webpack hot module replacement
if (module.hot) module.hot.accept()
For details on the module.hot API the webpack HMR docs are very helpful.

Categories

Resources