Text/Image Phaser 3 render issue - javascript

I am new to Phaser 3. I have an issue where when I run my game on a local host the text appears but the image does not. I have tried doing multiple things to get the image to load changing the folder routes, changing the folder in relation to the src folder, renaming the png, making sure the path is correct, making sure the tag is correct, trying other pngs. The dev tools show no errors in the browser. I am using parcel as my bundler not sure if that is the issue. Here are screenshots of my folder structure and what the browser looks like. Any ideas as to what I am doing wrong?
main.js
const Phaser= require('phaser');
const Game= require ("../src/scenes/Game")
var config = {
width: 800,
height: 500,
type: Phaser.AUTO,
};
var game = new Phaser.Game(config);
game.scene.add("game", Game);
game.scene.start("game");`
Game.js
const Phaser = require("phaser");
class Game extends Phaser.Scene {
preload() {
this.load.image("wind", "../assets/Wind.png");
}
create() {
const text = this.add.text(400, 250, "hello world");
text.setOrigin(0.5, 0.5);
this.add.image(400, 250, "wind");
}
}
module.exports = Game;
index.html
<html>
<head>
<title>A Storm's a Brewin</title>
</head>
<body>
<script src="./main.js"></script>
</body>`
package.json
{
"name": "stormbrewer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "parcel src/index.html",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"parcel-bundler": "^1.12.5",
"phaser": "^3.54.0"
}
}
Folder Structure
What the browser looks like

When you write
this.load.image("wind", "../assets/Wind.png"), that path is relative to the position of the file that is loaded by the browser.
The browser loads the file (usually) from the dist folder, not directly from the src.
I think you can solve by changing assets folder and telling Parcel how to pack your assets so that xxx/assets will be in dist/assets.
I usually use parcel-plugin-static-files-copy, and create a public folder along with src and put this in package.json
...
"staticFiles": {
"staticPath": "public"
},
...
Folder structure
package.json
public
| assets
| | any.png
src
| Game.js
Another solution could be to change how you reference the files that you "give" to Phaser (maybe with a require(...) or something). I know it's somehow possible but the first solution it's enough for my purposes so I didn't dig enough to explain it, but I think it's worth mention it.

Related

How do I exchange data between .pug file and a linked .js file without Node?

Is it possible to pass data from a .js file to a .pug file without using Node? I'm using a very basic setup where I run and bundle my project with Parcel.js. I'm not using a Node.js backend with Express and I do not aspire to. I simply want to be able to fetch data in my app.js-file and display it using Pug. But even this setup does not show the name-variable on the page:
index.pug
doctype html
html(lang="en")
head
title Homepage
body
p My name is #{name}
script(type="module", src="./app.js")
app.js
const name = "Holy Kiwi";
package.json
{
"name": "frontend-javascript-edhub-pug",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"start": "parcel index.pug",
"build": "parcel build index.pug"
},
"devDependencies": {
"#parcel/transformer-pug": "^2.0.0",
"parcel": "^2.0.0",
},
"dependencies": {
"pug": "^3.0.2"
}
}
Other things I've tried that didn't work
Exporting the variable from the app.js script: export const name = 'Kiwi';;
Creating a pug variable and then importing the script-variable into it: - const name = import { name } from './app.js';
I really hope you can help me out!
As you have the pug package installed, you can use the renderFile method:
const pug = require("pug");
const html = pug.renderFile("./path_to/index.pug", { name: "Holy Kiwi"});
The above produces the following string in the object html, and you can "display" it according to your needs:
<!DOCTYPE html><html lang="en"><head><title>Homepage</title></head><body><p>My name is Holy Kiwi</p><script type="module" src="./app.js"></script></body></html>

Parcel Bundler beautify, lint, and create .min.js

I'm new the world of automating/testing/bunding with JS and I've got parcel setup for the most part but I noticed that when it builds files, it does not actually save them with the .min.js part in the file name. I'm wondering if theres a way to do this without having to rename the build file manually.
I'm also trying to find a way to have parcel go through the original source files(the ones that you work on) and lint and beautify them for me
Here's what my package.json looks like
{
"name": "lpac",
"version": "1.3.1",
"description": "",
"dependencies": {},
"devDependencies": {
"parcel": "^2.0.0-rc.0"
},
"scripts": {
"watch": "parcel watch --no-hmr",
"build": "parcel build"
},
"targets": {
"lite-maps": {
"source": ["./path/file1.js", "./path/file2.js", "./path/file3.js"],
"distDir": "./path/build/"
}
},
"browserslist": "> 0.5%, last 2 versions, not dead",
"outputFormat" : "global",
}
I checked out the docs but I couldn't find anything on linting or beautifying with parcel. How can i go about doing that? If you have tutorial links to doing so please also share because resources/tutorials seem scarce for anything other than the basic watching and building files
Unfortunately, there is no out-of-the-box setting that can cause parcel javascript output look like [fileName].[hash].min.js instead of [fileName].[hash].js. The .min.js extension is just a convention to keep output files distinct from source files, though - it has no effect at runtime - and the fact that parcel does automatic content hashing makes it easy enough to tell this. And even though they don't have a .min.js extension, these output files are definitely still minified and optimized by default.
However, if you really, really want this anyways, it's relatively simple to write a Namer plugin for parcel that adds .min.js to all javascript output:
Here's the code:
import { Namer } from "#parcel/plugin";
import path from "path";
export default new Namer({
name({ bundle }) {
if (bundle.type === "js") {
const filePath = bundle.getMainEntry()?.filePath;
if (filePath) {
let baseNameWithoutExtension = path.basename(filePath, path.extname(filePath));
// See: https://parceljs.org/plugin-system/namer/#content-hashing
if (!bundle.needsStableName) {
baseNameWithoutExtension += "." + bundle.hashReference;
}
return `${baseNameWithoutExtension}.min.js`;
}
}
// Returning null means parcel will keep the name of non-js bundles the same.
return null;
},
});
Then, supposing the above code was published in a package called parcel-namer-js-min, you would add it to your parcel pipeline with this .parcelrc:
{
"extends": "#parcel/config-default",
"namers": ["parcel-namer-js-min", "..."]
}
Here is an example repo where this is working.
The answer to your second question (is there "a way to have parcel go through the original source files(the ones that you work on) and lint and beautify them for me") is unfortunately, no.
However, parcel can work well side-by-side with other command line tools that do this do this. For example, I have most of my projects set up with a format command in the package.json, that looks like this:
{
...
"scripts": {
...
"format": "prettier --write src/**/* -u --no-error-on-unmatched-pattern"
}
...
{
You can easily make that command automatically run for git commits and pushes with husky.

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.

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

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.

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

Categories

Resources