How does one set up a dead simple webpack-dev-server project? - javascript

I'm trying to set up a simple webpack JavaScript starter project with the absolute bare minimum to play with vanilla JavaScript. When I build the project, everything works fine. But if I try to run the project with webpack-dev-server, nothing updates when making changes.
This setup does not use a webpack.config.js file.
Does webpack-dev-server require a config file to make this function properly?
package.json
{
"name": "javascript-starter-project",
"version": "0.0.1",
"description": "A simple boilerplate JavaScript starter project.",
"license": "MIT",
"author": "...",
"main": "index.js",
"scripts": {
"build": "webpack",
"start": "webpack-dev-server --inline --open --port 8080"
},
"dependencies": {
"webpack": "^4.36.1"
},
"devDependencies": {
"prettier": "^1.18.2",
"webpack-cli": "^3.3.6",
"webpack-dev-server": "^3.7.2"
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JavaScript Starter Project</title>
</head>
<body>
<button id="button">Click me!</button>
<div id="output"></div>
<script src="dist/main.js"></script>
</body>
</html>
src/index.js
const button = document.getElementById("button");
const output = document.getElementById("output");
button.addEventListener("click", () => {
output.innerText = "Hello!~";
});
Now if I build this, clicking the button produces the "Hello!~" text as expected.
When I run npm start which uses webpack-dev-server, the same behavior happens. But when I make any changes ("Hello!~" edited to "Hello World!~"):
src/index.js
const button = document.getElementById("button");
const output = document.getElementById("output");
button.addEventListener("click", () => {
output.innerText = "Hello World!~";
});
... and refresh the page running at http://localhost:8080/ the changes are not reflected.
What am I missing? Do I need a webpack.config.js file to make this work?
EDIT:
The working setup now looks like this:
package.json
{
"name": "javascript-starter-project",
"version": "0.0.1",
"description": "A simple boilerplate JavaScript starter project.",
"license": "MIT",
"author": "...",
"main": "index.js",
"scripts": {
"build": "webpack",
"start": "webpack-dev-server --open --port 8080"
},
"dependencies": {
"webpack": "^4.36.1"
},
"devDependencies": {
"html-webpack-plugin": "^3.2.0",
"prettier": "^1.18.2",
"webpack-cli": "^3.3.6",
"webpack-dev-server": "^3.7.2"
}
}
webpack.config.js
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
})
]
};
src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JavaScript Starter Project</title>
</head>
<body>
<button id="button">Click me!</button>
<div id="output"></div>
</body>
</html>
src/index.js
const button = document.getElementById("button");
const output = document.getElementById("output");
button.addEventListener("click", () => {
output.innerText = "Hello!~";
});
Now, when I npm start and edit src/index.js, the changes are picked up! I was hoping there would be even less complexity than this, but this is pretty sparse so I'll take it.

The problem is the presence of <script src="dist/main.js"></script> in your index.html file. When you hit npm start or npm run start, webpack-dev-server spins up correctly. It serves the index.html and main.js file accordingly.
The webpack-dev-server has two jobs: In-memory bundling of assets and live-reloading. In-memory is required to support live reloading.
The problem happens when you make changes to index.js. Webpack indeed detects the changes, it builds but doesn't really emit bundled file back to the disk. It is built in-memory. In your case, since you have hardcoded the dist/main.js in your index.html, new main.js is not generated and you do not see the change on page refresh.
The quickest thing you can do is to run build script with watch mode. So use the following npm script in another terminal: "build": "webpack --watch". Now, on every save, the build would be generated and you can see the changes on refresh.
But this defeats the purpose of use webpack-dev-server. If this is the path, you wish to take then use something simple like http-server.
To fully harness the power of dev-server with live reloading, HMR, im-memory bundling, you would need a proper webpack.config.js file. Also, you must use html-webpack-plugin to generate index.html file so that live-reloading can work.

Related

How to set .js file as main in NW.js?

I followed NW.js' offical doc, but the window never appears.
If I switch package.json to "main": "index.html", window appears. but if I return to "main": "main.js", window doesn't appear.
This is my main.js:
var nw = require('nwjs');
nw.Window.open("index.html", {}, function(win) {});
I have to set "main": "main.js" because a module I want to use doesn't support .html file as "main".
Does anyone have a solution?
I'd be curious what module requires your main to be a JS file. It's pretty rare that you'd have an NW.js project that doesn't use an html file as the main (I strongly recommend using "main": "index.html").
Your problem is that var nw = require('nwjs'); is equivalent to doing nw = undefined. window.nw and global.nw are both already accessible at all times in the default context. You are basically deleting the thing you need.
index.html
<!DOCTYPE html>
<html>
<head>
<title>TEST</title>
</head>
<body>
<h1>Test<h1>
</body>
</html>
index.js
nw.Window.open('index.html');
package.json
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "nw ."
},
"devDependencies": {
"nw": "0.51.0-sdk"
},
"author": "Julien",
"description": "Test",
"license": "MIT"
}
Then just npm install && npm start. But again, you don't want this, you want "main": "index.html", it's just a lot less trouble.

Is there a way to pass a JSON object/Server data, to the main JS module generated from webpack?

HI everyone hope you are going well!
First of all I am a backend developer, not a frontend, but I do lots of front-end code as well however I never used Webpack in the past and I ended looking for webpack because of my requirements that are pretty much the follows:
Instead of use old JS way, I am using modules to decouple program logic into components
I need to bundle and minify those js into one bundlefile.
I need to pass server data to those functions inside the modules like JSON objects coming from the server.
For start I have the following configuration files for:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/main.js',
mode: 'development',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
};
package.json
{
"name": "testWebpack",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.13.0",
"webpack-cli": "^4.3.1"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
and the JS is pretty basic such for this example:
src\person.js
export default class Person
{
constructor()
{
this.Name = "Your name";
}
}
and src\main.js
import _ from 'lodash';
import p from './person';
export default function myTempFunction(allData)
{
// Lodash, currently included via a script, is required for this line to work
const value = _.join([allData.welcome, new p().Name], ' ');
console.log(value);
}
// myTempFunction({
// welcome: "Hello"
// });
dist\index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Getting Started</title>
</head>
<body>
<script src="main.js"></script>
<script type="module">
import myTempFunction from './main.js';
myTempFunction({
welcome: "Hello from the server"
});
</script>
</body>
</html>
when running I get an
The requested module './main.js' does not provide an export named 'default'
My idea is that in the server (I am using asp.net core) I am producing a JSON which I wanna pass to this modules and I need to pass the object inside the main function.
As you can see I have commented the myTempFunction inside src\main.js. If I uncomment that works but at that stage I don't have my serverData to pass.
I really searched on the web but I can't find any solution for this, maybe I am going something wrong in my thinking and I am feeling a bit odd.
At the same time It may feel right to do what I do inside the <script type="module"> but Make no sense because I want to get that function from webpack instead of loading the module using the Browser engine.
Any idea from the frontend devs where can give me an hint? I would love to hear your thoughts.

Meteor import directory test files not eagerly loading

Meteor version 1.7.0.5
Using meteortesting:mocha
I have a very simple meteor react app. I added a test file in imports/startup/simple-schema.tests.js
describe('Todos_item', function () {
console.log('Todo');
});
I was running npm run test-app so it should be logged in console but that file actually doesn't run. But when I added this snippet to my tests/main.js Todo is logged in console. So am I missing something.
My directory tree
package.json
{
"name": "meteor-bootstrap",
"private": true,
"scripts": {
"start": "meteor run",
"test": "meteor test --once --driver-package meteortesting:mocha",
"test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha",
"visualize": "meteor --production --extra-packages bundle-visualizer"
},
"dependencies": {
"#babel/runtime": "7.0.0-beta.55",
"meteor-node-stubs": "^0.4.1",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-router-dom": "^4.3.1",
"simpl-schema": "^1.5.3"
},
"meteor": {
"mainModule": {
"client": "client/main.js",
"server": "server/main.js"
},
"testModule": "tests/main.js"
},
"engines": {
"node": "8.11.4"
}
}
Any help will be greatly appreciated. Thanks in advance.
New Meteor apps since 1.7 have eager loading turned off by default (which is causing your problem)
The behaviour is controlled by the meteor section in your package.json.
To restore the eager loading behaviour for tests, delete the testModule key-value pair from your package.json. It should look like this:
"meteor": {
"mainModule": {
"client": "client/main.js",
"server": "server/main.js"
}
},
If you want to restore pre-1.7 behaviour for all files, just delete the whole meteor section from package.json
If you don't want to use eager loading, you will need to import all of your test files from the tests/main.js file
Also one thing to add when with #Fred answer importing test files have to use require not import though I am not sure is it due to my node version or not I am using my node version v6.11.1

Browserify result from npm build can not be instantiated in test file

I am working on converting a vanilla ES6 WebGL library to a package and am having some trouble / don't really know what I'm doing.
With the current library, we use browserify to compile it into a single file which is then copied over to our Ember project which is then mushed into our vendor file. When we develop the library we simply reference the compiled file in an HTML file local to the repo to debug and test.
Using an HTML test file local to the library is really nice because the Ember project is cumbersome and not ideal for testing the WebGL code.
I would like to have the library as a package.json or bower.json dependency of the Ember project so the workflow between the two projects is more mature and smooth. BUT I would like to maintain the debug workflow for the library so I don't have to deal with Ember constantly (Unless there is a better workflow out there for such a situation I don't know about).
Right now I'm having some troubles getting my npm build to properly browserify the library so it can be used in my HTML test file.
I've made a watered down version of the library's architecture in a demo repo here for you to see if you wish.
But, in essence, in the source folder I have two really boring classes, HelloWorld and TestClass.
src/HelloWorld.js
import TestClass from './TestClass';
class HelloWorld{
constructor(){
}
hello(){
let p = document.createElement('p');
let t = new TestClass();
p.innerHTML = "Hello World " + t.TestMember();
document.body.appendChild(p);
}
}
module.exports = HelloWorld;
src/TestClass.js
class TestClass{
constructor(){
this.member = 5;
}
TestMember(){
return "Test Member is: " + this.member;
}
}
module.exports = TestClass;
These are referenced in the library's entry point in src/index.js
src/index.js
module.exports = {
TestClass: require('./TestClass'),
HelloWorld: require('./HelloWorld')
};
Here is my package.json
{
"name": "webgl-render-package",
"version": "1.0.0",
"description": "Render Library",
"main": "lib/index.js",
"scripts": {
"prepublishOnly": "npm run build",
"build-js": "browserify lib/index.js > demo/RenderLibrary.js",
"build": "babel ./src -d ./lib && npm run build-js",
"lint": "eslint ./src",
"test": "nyc mocha --require babel-core/register"
},
"repository": {
"type": "git",
"url": "git+https://github.com/nhoughto5/NPM_PackageTest.git"
},
"author": "Anon",
"license": "ISC",
"bugs": {
"url": "https://github.com/nhoughto5/NPM_PackageTest/issues"
},
"homepage": "https://github.com/nhoughto5/NPM_PackageTeste#readme",
"devDependencies": {
"babel-cli": "6.26.0",
"babel-preset-env": "1.6.1",
"eslint": "4.19.0",
"mocha": "5.0.4",
"nyc": "11.6.0"
},
"nyc": {
"reporter": [
"lcov",
"text"
]
}
}
As you can see, in the scripts section I have build which babels all of the source files into the lib directory, and then the build-js script is run which in theory should browserify all of those files into the single RenderLibrary.js so I can test it in my test HTML file which you can see here:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Package Test</title>
<script src="RenderLibrary.js"></script>
<script>
function btnClick(){
var obj = new HelloWorld();
obj.hello();
console.log("Hello Again");
}
</script>
</head>
<body>
<button onclick="btnClick()">Press Me</button>
</body>
</html>
This all nicely compiles but in my test file I can't instantiate an instance of the two test classes.
When I click the Press Me button I get a nice Uncaught ReferenceError: HelloWorld is not definedeven though the compiled RenderLibrary.js file does define it.
I think you need to rethink this a bit. The reason you use browserify in the first place is to be able to write browser code in node style, i.e. using require.
So given packageTest.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Package Test</title>
<script src="testbundle.js"></script>
</head>
<body>
<button id="testbutton">Press Me</button>
</body>
</html>
You should really do browserify lib/test.js > demo/testbundle.js, where test.js contains code for the event handler. Also, in test.js you should require the HelloWorld class. It could look something like:
const domready = require('domready')
const HelloWorld = require('.').HelloWorld
domready(function () {
const button = document.getElementById('testbutton')
button.onclick = function () {
const obj = new HelloWorld()
obj.hello()
}
})
Result:
I've tested it using your repository. Pull request made here https://github.com/nhoughto5/NPM_PackageTest/pull/3

Simple Vue component not rendering

I am trying to learn Vue.JS, and the component I have made is not rendering on the page. This is my component:
import Vue from 'vue'
const card = new Vue({
el: '#card',
data: {
title: 'Dinosaurs',
content: '<strong>Dinosaurs</strong> are a diverse group of animals
from the clade <em>Dinosauria</em> that first appeared at the Triassic
period.'
}
})
This is my html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue Practice</title>
</head>
<body>
<div id="card">
<header>{{ title }}</header>
<div v-html="content"></div>
</div>
<script src="bundle.js"></script>
</body>
</html>
And this is package.json (I realize most of the dependencies belong in devDependencies):
{
"name": "vue-practice",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"bundle": "browserify -t babelify -t vueify -e main.js >
bundle.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babelify": "^7.3.0",
"browserify": "^14.4.0",
"vue": "^2.4.2",
"vueify": "^9.4.1"
},
"devDependencies": {}
}
When I load index.html in the browser, all it renders is {{ title }} and I am receiving no errors. Any explanation as to why this is happening would be appreciated!
vueify only transforms *.vue files, if you are going to use templating in your index.html then you need Vue compiler in order to compile the template in the browser (https://v2.vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only).
A good way to have things like that covered is to use a vuejs-template, if you are using Browserify there is one: https://github.com/vuejs-templates/browserify
But as you have almost everything up, you can only add what's missing for the compiler package, as stated in "Runtime + Compiler vs. Runtime-only" - "Browserify" section in Vue guide.
Add to your package.json:
{
"browser": {
"vue": "vue/dist/vue.common.js"
},
}
That will tell Browserify to use the full (also called standalone) Vue build on browser.
Another way is to not use templates in index.html but instead in a main component, like App.vue, for that you check out the template I linked above, it does it out of the box.

Categories

Resources