{"id":32635602,"url":"https://github.com/slothsoft/example-javascript-website","last_synced_at":"2026-06-22T21:31:34.084Z","repository":{"id":37843061,"uuid":"204727047","full_name":"slothsoft/example-javascript-website","owner":"slothsoft","description":"An example for setting up a static HTML website using well tested JavaScript.","archived":false,"fork":false,"pushed_at":"2022-12-04T09:22:15.000Z","size":463,"stargazers_count":2,"open_issues_count":6,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-13T19:48:10.817Z","etag":null,"topics":["example","html","javascript","website"],"latest_commit_sha":null,"homepage":"http://slothsoft.de","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slothsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-27T14:57:20.000Z","updated_at":"2025-10-13T13:42:40.000Z","dependencies_parsed_at":"2023-01-22T20:31:22.464Z","dependency_job_id":null,"html_url":"https://github.com/slothsoft/example-javascript-website","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/slothsoft/example-javascript-website","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slothsoft%2Fexample-javascript-website","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slothsoft%2Fexample-javascript-website/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slothsoft%2Fexample-javascript-website/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slothsoft%2Fexample-javascript-website/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slothsoft","download_url":"https://codeload.github.com/slothsoft/example-javascript-website/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slothsoft%2Fexample-javascript-website/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34666961,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-22T02:00:06.391Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["example","html","javascript","website"],"created_at":"2025-10-31T00:56:52.143Z","updated_at":"2026-06-22T21:31:34.078Z","avatar_url":"https://github.com/slothsoft.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Example JavaScript Website\r\n\r\n[![MIT Licence](https://img.shields.io/github/license/jenkinsci/java-client-api.svg?label=License)](http://opensource.org/licenses/MIT) [![Build Status](https://travis-ci.org/slothsoft/example-javascript-website.svg?branch=master)](https://travis-ci.org/slothsoft/example-javascript-website)\r\n\r\n- **Author:** [Stef Schulz](mailto:s.schulz@slothsoft.de)\r\n- **Repository:** \u003chttps://github.com/slothsoft/example-javascript-website\u003e\r\n- **Open Issues:** \u003chttps://github.com/slothsoft/example-javascript-website/issues\u003e\r\n- **Website:** [http://app.slothsoft.de](http://app.slothsoft.de/example-javascript-website)\r\n\r\nAn example for setting up a static HTML website using well tested JavaScript:\r\n\r\n![website](readme/02-website.png)\r\n\r\n**Content:**\r\n- [Preface](#preface)\r\n- [0. Setup Environment](#0-setup-environment)\r\n- [1. Dependency Management](#1-dependency-management)\r\n- [2. Transpile Code](#2-transpile-code)\r\n- [3. Tests](#3-tests)\r\n- [4. Create Website](#4-create-website)\r\n- [5. Deploy Finished Product](#5-deploy-finished-product)\r\n- [6. Hook to CI Server](#6-hook-to-ci-server)\r\n  - [Why is it important to use a CI server?](#why-is-it-important-to-use-a-ci-server)\r\n- [7. Localization](#7-localization)\r\n- [Conclusion](#conclusion)\r\n  - [Questions](#questions)\r\n  - [External Links](#external-links)\r\n\r\n\r\n# Preface\r\n\r\nLet me preface this document by saying: I'm not a JavaScript developer. I don't *want* to be a JavaScript developer. I've over ten years in Java and I don't plan to change that any time soon. \r\n\r\nBut I'm a firm believer of using the right tool for the job, so I'm trying to learn how to swing the JavaScript pocket knife, just in case I need something different than my Java hammer someday.\r\n\r\nI was sorely disappointed to learn there is evidently no standard environment to develop JavaScript, so I'm trying to figure out how to do it on my own.\r\n\r\nFor Java the de facto standard is to use Maven, which does the following:\r\n\r\n1. Manage dependencies\r\n2. Compile the code\r\n3. Test\r\n4. Create a distribution (JAR for Java)\r\n5. Deploy the finished product\r\n6. Run on CI server\r\n\r\nSo I figure the same is needed for a JavaScript project (except we don't need a compiler, but maybe a transpiler (to create older code that is supported by more browsers) and / or a minimizer (to strip whitespaces and stuff like that)).\r\n\r\nSo that's what I'm trying to get into this environment.\r\n\r\nOh, and localization, even though that's a plain Java feature and not Maven. But it's needed for every application. Note that this is no tutorial, it's a diary where I try to understand what I'm doing.\r\n\r\nSo let's go!\r\n\r\n\r\n\r\n# 0. Setup Environment\r\n\r\nThe only thing almost everyone seems to agree on is that we need NodeJS. You can get it from [nodejs.org](https://nodejs.org/en/). NodeJS let's you run JavaScript outside of the browser. Which can be used to create JavaScript servers (I've yet to find out why that would be a *good* idea) or of course for executing tests.\r\n\r\nSo if you've installed NodeJS correctly you should get the following output on the command line:\r\n\r\n```\r\n\u003enode --version\r\nv10.16.3\r\n```\r\n\r\n\r\n\r\n# 1. Dependency Management\r\n\r\nFor this setup dependency management is done by NodeJS's very own package manager: npm.\r\n\r\nIt should be available if NodeJS is installed, so check that by using the command line:\r\n\r\n```\r\n\u003enpm --version\r\n6.11.2\r\n```\r\n\r\nSince npm updates more frequently than NodeJS it's probable this version is outdated. Use this to update:\r\n\r\n```\r\nnpm install npm@latest -g\r\n```\r\n\r\nSo now we can create a project:\r\n\r\n```\r\nmkdir example\r\ncd example\r\nnpm init\r\n```\r\n\r\nnpm will now play twenty questions with you, but you can just press enter to use the defaults.\r\n\r\nThis will generate a file _package,json_. A basic one looks something like this:\r\n\r\n```json\r\n{\r\n  \"name\": \"example\",\r\n  \"version\": \"1.0.0\",\r\n  \"description\": \"My first project\",\r\n  \"main\": \"index.js\",\r\n  \"scripts\": {\r\n    \"test\": \"echo \\\"Error: no test specified\\\" \u0026\u0026 exit 1\"\r\n  },\r\n  \"author\": \"Stef Schulz \u003cs.schulz@slothsoft.de\u003e\",\r\n  \"license\": \"MIT\"\r\n}\r\n\r\n```\r\n\r\nYou can see my _[package.json](package.json)_ for a more comprehensive example. Although maybe finish reading this document first, some properties will be explained.\r\n\r\n\r\n\r\n\r\n\r\n\r\n# 2. Transpile Code \r\n\r\nSo evidently NodeJS is only for creating server applications with JavaScript. Maybe I'll tackle this later but right now I want to create a simple website. \r\n\r\nSo... simple website, right? I created a small HTML page ([index.html](dist/index.html)), a very basic CSS file ([style.css](dist/resources/css/style.css)) and copied an image from my last vacation ([image](dist/resources/images/DSC00372.jpg)). The structure of the project is from [appcropolis](http://appcropolis.com/blog/web-technology/organize-html-css-javascript-files/):\r\n\r\n![structure](readme/02-structure.png)\r\n\r\nCheck out the HTMl file. The important line is the following:\r\n\r\n```html\r\n\u003cb\u003ePrice for Family:\u003c/b\u003e $\u003cspan id=\"family-price\"\u003e\u003c/span\u003e\r\n```\r\n\r\nIt gives us an entry point for our JavaScript. Speaking of which I created a file _[src/box-office.js](src/box-office.js)_ with a legendary algorithm:\r\n\r\n```js\r\nfunction calculatePrice(personCount) {\r\n\treturn 80.0 * personCount;\r\n}\r\n```\r\n\r\nAnd now I want to somehow get the result of the function into my HTML. So far everything's pretty standard, but now we'll work with NodeJS.\r\n\r\nNodeJS wants to have an actual application that does stuff, so let's create a  _[src/main.js](src/main.js)_:\r\n\r\n\r\n```js\r\nvar calculatePrice = require('./box-office.js')\r\n\r\ndocument.getElementById('family-price').innerHTML = calculatePrice(4);\r\n```\r\n\r\nNow how do we get the NodeJS application into our nice little website? The answer is:  [browserify](https://github.com/browserify/browserify).\r\n\r\nWe'll install it via command line:\r\n\r\n```\r\nnpm install --save-dev browserify\r\n```\r\n\r\n(The tutorial on the browserify page suggests using `npm install -g browserify` to install it globally. For me the above worked better for some reason.)\r\n\r\nDuring the execution of the above command line the following happens:\r\n\r\n1. npm creates a file _[package-lock.json](package-lock.json)_ that contains all dependencies; it also tells us `You should commit this file.` (but most modules I saw on GitHub still don't)\r\n1. a folder _node\u0026#x5f;modules/_ is created; this folder contains the dependencies as NodeJS modules; there is no reason to commit this folder, since you can generate it from the _package-lock.json_\r\n\r\nNext we'll create a script in the _package.json_ file that bundles our \"main\" application into a file \"bundle.js\":\r\n\r\n```json\r\n  \"scripts\": {\r\n    \"bundle\": \"browserify src/main.js -o dist/resources/js/bundle.js\",\r\n  }\r\n```\r\n\r\nRun it via `npm browserify` and voilá: we have everything bundled nicely. We'll just add the script into our HTML page via the following line:\r\n\r\n```html\r\n\u003cscript src=\"resources/js/bundle.js\"\u003e\u003c/script\u003e\r\n```\r\n\r\n(I found out the hard way that this only works directly before the closing `\u003c/body\u003e` tag.)\r\n\r\n![website](readme/02-website.png)\r\n \r\nIsn't it nice?\r\n\r\nBut wait... the _bundle.js_ is still very big. So we'll add another module to minimize it, [Butternut](https://github.com/Rich-Harris/butternut).\r\n\r\n```\r\nnpm install --save-dev butternut\r\n```\r\n\r\n(I'll keep adding these modules locally, because I have no idea why that would be a bad idea.)\r\n\r\nAnd then we extent the script:\r\n\r\n```json\r\n  \"scripts\": {\r\n    \"bundle\": \"browserify src/main.js | squash \u003e dist/resources/js/bundle.js\",\r\n  }\r\n```\r\n\r\nEven for such a small application this step saved us over 100 bytes (16% of the length of the file). \r\n\r\nSo all is good but it's really annoying to create the _bundle.js_ by hand. We'll just add another bundle to do this for us: [watchifiy](https://www.npmjs.com/package/watchify).\r\n\r\nWe'll install it via:\r\n\r\n```\r\nnpm install --save-dev watchify\r\n```\r\n\r\nAnd we'll add another script:\r\n\r\n```json\r\n  \"scripts\": {\r\n    \"bundle\": ...\r\n    \"watch\": \"watchify src/main.js -o dist/resources/js/bundle.js -v\"\r\n  }\r\n```\r\n\r\nRun it via `npm watch` and you'll see the following anytime you change one of the files in _src/_:\r\n\r\n```\r\n860 bytes written to dist/resources/js/bundle.js (0.03 seconds) at 22:14:09\r\n860 bytes written to dist/resources/js/bundle.js (0.01 seconds) at 22:14:18\r\n860 bytes written to dist/resources/js/bundle.js (0.01 seconds) at 22:14:20\r\n```\r\n\r\nIf you don't like the output, remove \"-v\" from the above script.\r\n\r\nSo now we're able to create a tightly packaged _bundle.js_ and are able to recreate it on any change of the source files. Nice.\r\n\r\n\r\n\r\n# 3. Tests\r\n\r\nFor creating tests I used [QUnit](https://qunitjs.com/) because it looked simple. As with everything here there are a bunch of options around. I've personally worked with [jasmine](https://jasmine.github.io/) and [mocha](https://mochajs.org/) as well.\r\n\r\nUsing QUnit the tests for the legendary algorithm™ look like this:\r\n\r\n```js\r\nQUnit.module(\"calculatePrice()\", function() {\r\n\tQUnit.test(\"for 0 persons\", function(assert) {\r\n\t\tassert.equal(calculatePrice(0), 0.0);\r\n\t});\r\n\tQUnit.test(\"for 1 person\", function(assert) {\r\n\t\tassert.equal(calculatePrice(1), 80.0);\r\n\t});\r\n\tQUnit.test(\"for 2 persons\", function(assert) {\r\n\t\tassert.equal(calculatePrice(2), 160.0);\r\n\t});\r\n\t// ...\r\n});\r\n```\r\n\r\nFor me the most problematic part was the definition of equal: [equal(actual, expected)](https://api.qunitjs.com/assert/equal). Because I'm used to writing it the other way around (expected, then actual). \r\n\r\nIf you copy the QUnit example HTML page you can even see the tests work:\r\n\r\n```html\r\n\u003c!DOCTYPE html\u003e\r\n\u003chtml\u003e\r\n\u003chead\u003e\r\n\t\u003cmeta charset=\"utf-8\"\u003e\r\n\t\u003cmeta name=\"viewport\" content=\"width=device-width\"\u003e\r\n\t\u003ctitle\u003eQUnit Example\u003c/title\u003e\r\n\t\u003clink rel=\"stylesheet\" href=\"https://code.jquery.com/qunit/qunit-2.9.2.css\"\u003e\r\n\u003c/head\u003e\r\n\u003cbody\u003e\r\n\t\u003cdiv id=\"qunit\"\u003e\u003c/div\u003e\r\n\t\u003cdiv id=\"qunit-fixture\"\u003e\u003c/div\u003e\r\n\t\u003cscript src=\"https://code.jquery.com/qunit/qunit-2.9.2.js\"\u003e\u003c/script\u003e\r\n\t\u003cscript src=\"../src/box-office.js\"\u003e\u003c/script\u003e\r\n\t\u003cscript src=\"../test/box-office-test.js\"\u003e\u003c/script\u003e\r\n\u003c/body\u003e\r\n\u003c/html\u003e\r\n```\r\n\r\n(Example for a file _dist/test.html_)\r\n\r\nThe result looks something like this:\r\n\r\n![qunit](readme/03-qunit.png)\r\n\r\nBut we know if a human has to check the tests, then the human will become the problem, so I'd rather have the build process check the tests.\r\n\r\nFirst we want to install QUnit to the project using this command line:\r\n\r\n```\r\nnpm install --save-dev qunit\r\n```\r\n\r\nAfter the installation it's time to tell the project to run QUnit as test, so we'll change the following lines of the _package.json_:\r\n\r\n```json\r\n  \"scripts\": {\r\n    \"bundle\": ...\r\n    \"watch\": ...\r\n    \"test\": \"qunit\"\r\n  }\r\n```\r\n\r\nIf we run that now via `npm test` you'll get the following error:\r\n\r\n```\r\nReferenceError: calculatePrice is not defined\r\n```\r\n\r\nIt's clear that the test doesn't know the file with the  legendary algorithm™, so we'll add:\r\n\r\n```js\r\ncalculatePrice = require('../src/box-office.js')\r\n```\r\n\r\n...and export the corresponding method:\r\n\r\n```js\r\nmodule.exports = function calculatePrice(personCount) {\r\n\treturn 80.0 * personCount;\r\n}\r\n```\r\n\r\n(**Note:** If you followed this step by step then the _dist/test.html_ will stop working after these two changes, because `require()` and `module.exports` are NodeJS functions.)\r\n\r\nExecute the tests again using npm and you'll get something like that:\r\n\r\n```\r\nTAP version 13\r\nok 1 calculatePrice() \u003e for 0 persons\r\nok 2 calculatePrice() \u003e for 1 person\r\nok 3 calculatePrice() \u003e for 2 persons\r\nok 4 calculatePrice() \u003e for 3 persons\r\n1..4\r\n# pass 4\r\n# skip 0\r\n# todo 0\r\n# fail 0\r\n```\r\n\r\nSo tests now work.\r\n\r\n\r\n\r\n\r\n# 4. Create Website\r\n\r\nSince we deploy the website directly to the server we don't need to do something special here. Our script \"bundle\" already creates a nice working website in the _dist/_ folder.\r\n\r\n\r\n\r\n# 5. Deploy Finished Product\r\n\r\nSo now we have a website ready to deploy. We want to deploy it to a server, but what else do we want?\r\n\r\n1. Test the code (stop if there are errors)\r\n1. Bundle the code (because \"watch\" doesn't minify the code)\r\n1. Deploy\r\n\r\nWe can already do the first two. So let's tackle the last one.\r\n\r\nThere is a pretty easy to use module already in NodeJS to deploy websites: [ftp-deploy](https://www.npmjs.com/package/ftp-deploy). So we install it:\r\n\r\n```\r\nnpm install --save-dev ftp-deploy\r\n```\r\n\r\nSince I want to commit the actual code to deploy without compromising my server's login and password, I have two files: _[deploy.js](deploy.js)_ for the general config and _[deploy-config.json](deploy-config.json)_ for security relevant info (this file should not be committed).\r\n\r\nSo the _deploy.js_ looks like this:\r\n\r\n```js\r\nvar FtpDeploy = require('ftp-deploy');\r\nvar ftpDeploy = new FtpDeploy();\r\n\r\nvar serverConfig = require('./deploy-config.json');\r\nvar generalConfig = {\r\n    port: 21,\r\n    localRoot: __dirname + '/dist/',\r\n    remoteRoot: '/htdocs/app/example-javascript-website/',\r\n    include: ['*', '**/*'],\r\n    deleteRemote: true,\r\n    forcePasv: true\r\n};\r\nvar mergedConfig = {...generalConfig, ...serverConfig};\r\n\r\n\r\nftpDeploy.deploy(mergedConfig, function(err, res) {\r\n    if (err) console.log(err)\r\n    else console.log('Finished:', res);\r\n});\r\n```\r\n\r\nThis script overwrites the config of `generalConfig` with whatever is present in the _deploy-config.json_. Username, password and host are mandatory, but you can overwrite the port or something else if you feel like it. \r\n\r\nI'd leave a template in the repository, but mark the file as non-committable (`--assume-unchanged` in Git). Then each committer would have to replace the authorization data once upon checkout.  \r\n\r\nWe run the script via `node deploy.js` which leaves the deploy script as:\r\n\r\n```json\r\n  \"scripts\": {\r\n    \"bundle\": ...\r\n    \"watch\": ...\r\n    \"test\": ...\r\n    \"deploy\": \"npm run test \u0026\u0026 npm run bundle \u0026\u0026 node deploy.js\"\r\n  }\r\n```\r\n\r\n\r\n\r\n# 6. Hook to CI Server\r\n\r\nBefore letting a CI server do anything to the code, we need to commit it. You can use this handy [.gitignore template for NodeJS](https://github.com/github/gitignore/blob/master/Node.gitignore) to figure out what to commit.\r\n\r\nHooking the project to a CI server is incredibly easy for GitHub projects. That's why I love [Travis](https://travis-ci.org/).\r\n\r\nYou only create a file _.travis.yml_:\r\n\r\n```\r\nlanguage: node_js\r\nnode_js:\r\n  - \"stable\"\r\n  - \"10\"\r\n```\r\n\r\nThe entries below \"node_js\" tell Travis which NodeJS versions to test against. For simplicity's sake I'll use 10 (the current long term support) and the last stable version (currently 12).\r\n\r\nOn default Travis executes `npm test`, which works nicely for us. \r\n\r\nLog into Travis using your GitHub account, search your repository in your list and enable it: \r\n\r\n![travis](readme/06-travis.png)\r\n\r\nThat's it. You can trigger a build manually or wait for Travis to react to a commit. \r\n\r\nThe output will be the same as for the regular test runs. You can find this project's Travis configuration [here](https://travis-ci.org/slothsoft/example-javascript-website).\r\n\r\n## Why is it important to use a CI server? \r\n\r\n- You can check if your code (and development environment) has dependencies to something that's just on your machine, e.g. when I added Travis I found out I was still missing some dependencies \r\n- Checks that the code in your repository still works, even if you forgot to run some of the tests (or _all_ the tests)\r\n- If you work with others, frequent feedback from the tests allows for bugs to be found much sooner, so that the original author might still be able to fix them\r\n- You can test the code against different versions of dependencies \r\n- And really, if you can automate some tasks, why wouldn't you? Tedious tasks like deploying to a development server should be done by a CI server.\r\n\r\n\r\n\r\n# 7. Localization\r\n\r\nTo localize the app I used [localizify](https://github.com/noveogroup-amorgunov/localizify), because it has no other dependencies:\r\n\r\n```\r\nnpm install localizify --save\r\n```\r\n\r\nNote that this is the first time a dependency is added to the property \"dependencies\" instead of \"devDependencies\" in the _package.json_ file.\r\n\r\nThe tutorial for localizify is pretty straight forward. Since I don't really want to complicate my small HTML page, I added the localization only for the currency symbol.\r\n\r\nSo the JSON files for translating look like this:\r\n\r\n[en.json](en.json):\r\n\r\n```json \r\n{\r\n  \"currency\": \"${value}\",\r\n}\r\n```\r\n\r\n[de.json](de.json) (or any other EU country): \r\n\r\n```json\r\n{\r\n  \"currency\": \"{value} €\",\r\n}\r\n```\r\n\r\nI created another JavaScript file to include these messages files (so that the test can use them as well) inside the file - _[src/init-i18n.js](src/init-i18n.js)_: \r\n\r\n```js\r\nconst localizify = require('localizify');\r\n\r\nconst en = require('./messages/en.json');\r\nconst de = require('./messages/de.json');\r\n\r\nlocalizify.add('en', en).add('de', de);\r\n\r\nvar userLang = navigator.language || navigator.userLanguage; \r\nlocalizify.setLocale(userLang);\r\n\r\nmodule.exports = localizify;\r\n```\r\n\r\nAnd finally copied our legendary algorithm™ and its test so I can create versions with localization:\r\n\r\n- _[src/international-box-office.js](src/international-box-office.js)_\r\n- _[test/international-box-office-test.js](test/international-box-office-test.js)_\r\n\r\nSo now we can open two versions of the website:\r\n\r\n![i18n](readme/07-i18n.png)\r\n\r\nLeft a German browser, right an American English one. \r\n\r\n\r\n\r\n# Conclusion\r\n\r\nSo now I've created a working environment to create a static HTML website with well tested NodeJS JavaScript.  And if you followed this guide you might have, too. Or you can just download this repository if you like. I bet I will in the future. \r\n\r\nIf you find mistakes of any kind just [write me an email](mailto:s.schulz@slothsoft.de) or [raise an issue](\u003chttps://github.com/slothsoft/example-javascript-website/issues\u003e). I love to learn new stuff, so I'll be thrilled to hear from you! \r\n\r\n\r\n\r\n## Questions\r\n\r\n**Every time I install a new module, _package-lock.json_ will get scrambled and random previous installed modules will vanish. Why?**\r\n\r\nI assume this has to do with the following question. The dependencies were missing from the _package.json_, so they weren't taking into account for the generation of the _package-lock.json_.\r\n\r\n\r\n**Some modules inserted themselves into _package.json_ -\u003e \"dependencies\" or \"devDependencies\". Most didn't. Why?**\r\n\r\nSometimes there is the following warning during the installation:\r\n\r\n```\r\nnpm WARN saveError EPERM: operation not permitted, rename 'S:\\path\\to\\project\\package.json.3710518402' -\u003e 'S:\\path\\to\\project\\package.json'\r\n```\r\n\r\n(Which really, _really_ should be an error, because it prevents the dependency from being permanent.)\r\n\r\nIn my case the folder _node\u0026#x5f;modules/_ was set to read only. After removing that flag the above warning vanished and the dependency was added to the _package.json_ file correctly.\r\n\r\n\r\n\r\n## External Links\r\n\r\nI've read a lot of stuff to come this far (which is not very far to be sure), but here are some of my resources:\r\n\r\n- [Configuring a basic environment for JavaScript development](https://italonascimento.github.io/configuring-a-basic-environment-for-javascript-development/)\r\n- [How to Build a reusable Javascript development environment.](https://medium.com/the-andela-way/how-to-build-a-reusable-javascript-development-environment-f13146b77fdf)\r\n- [A crash course on testing with Node.js](https://hackernoon.com/a-crash-course-on-testing-with-node-js-6c7428d3da02)\r\n- [How to organize your HTML, CSS, and Javascript files](http://appcropolis.com/blog/web-technology/organize-html-css-javascript-files/)\r\n\r\nUsed modules and other resources:\r\n\r\n- [browserify on GitHub](https://github.com/browserify/browserify)\r\n- [Butternut](https://github.com/Rich-Harris/butternut)\r\n- [watchifiy](https://www.npmjs.com/package/watchify)\r\n- [QUnit](https://qunitjs.com/)\r\n- [.gitignore Template for NodeJS](https://github.com/github/gitignore/blob/master/Node.gitignore)\r\n- [Travis](https://travis-ci.org/)\r\n- [localizify](https://github.com/noveogroup-amorgunov/localizify)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslothsoft%2Fexample-javascript-website","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslothsoft%2Fexample-javascript-website","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslothsoft%2Fexample-javascript-website/lists"}