javascript

development, document









Company / Organization: becke.ch
(I suggest to use here your domain name (or company name) which is registered and globally unique)

Scope: 0.0 (language=en;language=default;technology=js;organization=becke.ch;)
(ID and key/values of the scope this Module / Artifact / Component / Work-Product is valid for. The ID is as well part of the name of this Module / Artifact / Component / Work-Product i.e. is exposed towards outside of the Module / Artifact / Component / Work-Product. See as well: [1] and [2])

Version: 1.0.0
(Major[.Minor[.Patch[Build]]] – e.g. 2.3.5-0041 – the Major[.Minor] version is as well exposed towards outside of the Module / Artifact / Component / Work-Product. Different “.Patches” respective “.Build” versions are described in the same Major[.Minor] Module / Artifact / Component / Work-Product using substructures. In the current context the substructures would be reflected in sub-chapters. See as well: [1] and [2])

File-name: becke-ch--javascript--s0-0-v1-0.odt



Document Version History

Version

Date

Author

Description

1.0.0

15.11.2015

Raoul Becke

Initial version





Module / Artifact / Component / Work-Product Version History

Version

Date

Author

Requirements

Components Changed

1.0.0

15.11.2015

Raoul Becke

Create documentation on JavaScript with the following content: Directory & Naming Convention, NPM (Package Manager for Java-Script) (Installation, Setup, Directory Structure, Unit Testing, Intellij, Workflow, Publishing), YARN, Private registry/repository (Nexus Repository OSS), Separate File versus In-Line HTML, Data Structure (Types, Pointers, String, Function, DOM), Object Orientation (Inheritance), Functionality (Parameters, Recursive Function, Nested Function, Copy-Paste, Log, RegExp, Cursor Positioning, Contenteditable), Performance, JSON, TypeScript, AngularJS 1 (Download, Documentation, Java, View, Controller, Scope, Filter, Directive, JSON, TreeView, Call Function, Server Communication), Angular 2

This document










Table of Contents

1. Introduction 8

2. Directory & Naming Convention 8

3. NPM (Package Manager for Java-Script) 9

3.1. Node.js 9

3.2. Installing Node.js and updating npm 10

3.3. Setup 11

3.4. npm install 12

3.5. Directory Structure 13

3.6. Documentation 13

3.6.1. API Reference 13

3.6.1.1. Modify Home Text 13

3.6.1.2. Change method name (aliasing) 14

3.6.1.3. Intellij 15

3.6.1.4. NPM 15

3.6.2. README.md 16

3.6.2.1. Command Line & NPM 16

3.7. Unit Testing 16

3.7.1. Assertions 17

3.8. IntelliJ 17

3.8.1. Intellij Settings 17

3.9. Workflow 18

3.9.1. package.json 18

3.9.2. Create a new Node.js module 21

3.9.2.1. Intellij – option a) new (npm) module from existing sources 22

3.9.2.2. Intellij – option b) new (npm) module from static we 25

3.9.3. Publishing a package 26

3.9.3.1. Create an NPM account (optional) 26

3.9.3.2. Logging into npm (optional) 27

3.9.3.3. Logging into nexus – authentication 27

3.9.3.4. Publishing the package 28

3.9.3.4.1. ERROR 28

3.9.3.5. Deleting a published package (nexus repository) 29

3.10. Publishing Node.js Module To Ivy Repository 31

4. YARN 32

4.1. Getting started 32

4.1.1. Installation 32

4.1.2. Setup 33

4.1.3. Intellij Settings 33

4.2. Workflow 34

4.2.1. Create a new project 34

4.2.1.1. Intellij – new (npm) module 34

4.2.2. Publishing a package 34

4.2.2.1. Create an NPM account (optional) 35

4.2.2.2. Logging into npm (optional) 35

4.2.2.3. Publishing the package 35

4.2.2.3.1. ERROR 35

4.2.3. Upgrade packages 36

4.2.3.1. ERROR 36

5. Private registry/repository 36

5.1. CouchDB 37

5.1.1. Installation 37

5.1.1.1. Source 37

5.1.1.2. Binary 39

5.1.2. Setup 39

5.2. Nexus Repository OSS 40

5.2.1. Prerequisites and Conventions 40

5.2.2. Installation 41

5.2.3. Setup 41

5.2.4. Start 42

5.2.5. Proxying npm Registries 43

5.2.6. Private npm Registries 44

5.2.7. Grouping npm Registries 45

5.2.8. Security 47

5.2.8.1. Create User 47

5.2.9. Error 47

6. Separate File versus In-Line HTML 50

6.1. In-Line HTML 50

6.2. Separate File 51

7. Data structure 51

7.1. Types 51

7.1.1. typeof and instanceof (checking for array or function type) 51

7.2. Pointers 52

7.3. String 52

7.3.1. string.charAt(position) 52

7.3.2. Check if character is string 52

7.3.3. Empty string 53

7.3.4. indexOf (check for substring) 53

7.3.5. Escape Characters 53

7.3.6. Convert Octal to Hexadecimal 54

7.4. Function 54

7.4.1. Reflection – invoke function and parameters dynamically: call & apply 54

7.5. HTML DOM 54

7.5.1. nodeType Property 57

7.5.2. nodeName Property 57

8. Object Orientation (OO) 58

8.1. Inheritance 58

8.1.1. ERROR 58

9. Functionality 59

9.1. Function parameters 59

9.2. Recursive function and for loop 60

9.2.1. Error JavaScript - cannot set property of undefined 60

9.3. Nested function 61

9.3.1. Performance 61

9.4. Copy - Paste 62

9.5. console.log 62

9.5.1. Chrome 63

9.6. Regular Expression - RegExp 63

9.6.1. Unicode Support 64

9.6.2. Unicode Character 'EM SPACE' (U+2003) versus tabulator 64

9.6.3. Back-Reference 64

9.7. Cursor position & positioning 64

9.7.1. Retrieve entire text 66

9.7.2. Calculate Position of selected text 66

9.7.3. Retrieve the position (X,Y) of an HTML element 67

9.8. contenteditable 67

9.9. Creating a link without underscore 67

9.10. Error 67

10. Performance 68

11. JSON 68

11.1. Escape Characters 69

12. Typescript 70

12.1. ERROR 72

13. AngularJS 1 73

13.1. Downloading 73

13.2. Documentation (offline) 74

13.2.1. Error GET /angular.min.js" Error (404): "Not found" 74

13.3. Setup rich client (java) 74

13.4. Setup web client 75

13.5. Sample Hello World 75

13.6. Module 75

13.6.1. Error: $injector:unpr - Unknown Provider 77

13.7. View 77

13.7.1. Invoke function after view initialization / page load: ngInit & angular.element(document).ready 77

13.7.2. Key Event Listening 78

13.7.2.1. Cursor Key Listening 78

13.7.2.2. Watch for a key-combination 78

13.7.3. ng-repeat 79

13.7.3.1. ERROR: [ngRepeat:dupes] 81

13.8. Controller 82

13.8.1. Share data between controllers 82

13.9. Scope 82

13.9.1. Watch multiple $scope attributes 82

13.10. Filter 83

13.10.1. AngularJS : Insert HTML into view 83

13.11. Directive 83

13.11.1. Passing objects to directives via isolated scope 84

13.11.2. Acting on events 85

13.11.3. contenteditable 85

13.11.4. Errors 86

13.11.5. Error: $digest already in progress 87

13.12. JSON 88

13.12.1. json 88

13.12.2. angular.fromJson 88

13.12.3. How should I escape strings in JSON? 89

13.13. Tree View 89

13.14. Use button to navigate page as a link 89

13.15. Call angularjs function using jquery/javascript 90

13.16. Server communication 91

13.16.1. Multipart Upload & File Upload 91

13.16.2. Session 93

13.16.3. ERROR 94

14. Angular 2 95

14.1. Setup 95

14.1.1. Initial Setup 95

14.1.2. Project Setup 96

14.2. Development 98

14.2.1. app.component.ts 98

14.2.2. npm start 100

14.2.3. Typescript - tsconfig.json 101

14.2.4. boot.js 101

14.2.5. index.html 102

14.2.6. Import Libraries & Modules 102

14.2.6.1. Add TypeScript Definitions 103

14.2.6.2. Import JS Files/Libraries 103

14.2.6.3. Import NPM Modules 104

14.2.6.4. ERROR 106

14.2.7. Html Elements: Textarea, Button, Input, Binding 106

14.3. Build & Deploy 108

14.4. Typescript - tsconfig.json 109

14.5. package.json 110

14.6. Migration AngularJS1 -> AngularJS2 110

15. Landscape 111

16. References and glossary 112

16.1. References 112

16.2. Glossary (terms, abbreviations, acronyms) 112

A. Appendix 113

A.1. Appendix A1 113





Illustration Index

Illustration 1: Illustration sample 6





Index of Tables

Table 1: Table sample 6

Table 2: References 9

Table 3: Glossary 9



1. Introduction

This document captures all the issues and solutions I’ve come across so far during my JavaScript path.



2. Directory & Naming Convention

AngularJS: angularjs/controller/becke-ch--PRODUCT--sX-Y-Z-vA-B--USECASE--pl--client.js

Further context root sub-directories:








3. NPM (Package Manager for Java-Script)

https://ponyfoo.com/articles/choose-grunt-gulp-or-npm

https://www.npmjs.com/

npm makes it easy for JavaScript developers to share and reuse code, and it makes it easy to update the code that you're sharing.



3.1. Node.js

https://nodejs.org/en/

...

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.

http://openmymind.net/2012/2/3/Node-Require-and-Exports/

http://wesbos.com/javascript-modules/

In Node, things are only visible to other things in the same file. By things, I mean variables, functions, classes and class members.



the fundamental Node building block is called a module which maps directly to a file



To expose things we use module.exports and export everything we want:

becke-ch--regex--s0-0-v1--base--pl--lib.js:

function Regex(pattern, flags) {

this.pattern = pattern;

this.flags = flags;

if (!pattern) {

this.regex = new RegExp(pattern, flags);

}

this.regexGroupStructure = getRegexCompleteGroupingStructure(pattern);

try {

this.regex = new RegExp(this.regexGroupStructure[0][2], flags);

} catch (e) {

new RegExp(pattern, flags);

}

}



function initialize() {

if (!(typeof module === "undefined")) {

module.exports = Regex;

}

}

initialize();

Important to mention here is that I want to use the JavaScript as well outside of Node in plain old JavaScript environment and therefore I put the module-export into an initializer function which checks whether we are in a Node environment or a plain JavaScript environment!



require is used to load a module, which is why its return value is typically assigned to a variable:

var assert = require('assert');

var Regex = require('../src/becke-ch--regex--s0-0-v1--base--pl--lib');

describe('exec', function () {

it('regex abcdef applied on abcdef', function () {

var pattern = 'abcdef';

var str = 'abcdef';

var regex = new Regex(pattern);

var result = regex.exec(str);

var regexp = new RegExp(pattern);

var resultp = regexp.exec(str);

//console.log(result);

assert.equal(resultp.length, result.length);

assert.equal(resultp.input, result.input);

for (var i = 0; i < resultp.length; i++) {

assert.equal(resultp[i], result[i]);

}

assert.equal(1, result.index.length);

assert.equal(0, result.index[0]);

});

});





3.2. Installing Node.js and updating npm

https://docs.npmjs.com/getting-started/installing-node

https://nodejs.org/en/download/

Download to: /tool/node-v4.2.4-linux-x64.tar.gz

Extract to: /tool/node-v4.2.4-linux-x64

Installing Node.js



If you're using Mac or Windows, the best way to install Node.js is to use one of the installers from nodejs.org. If you're using Linux, you can use the installer, or you can check NodeSource's binary distributions to see whether or not there's a more recent version that works with your system.



Test: Run node -v. The version should be higher than v0.10.32.

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v1:/tool/node-v4.2.4-linux-x64/bin$ ./node -v

v4.2.4

https://github.com/nodejs/node-v0.x-archive/issues/3911

admin--s0-v1@hp-elitebook-840-g1--s0-v1:/tool/node-v4.2.4-linux-x64/bin$ sudo ln -s /tool/node-v4.2.4-linux-x64/bin/node /usr/bin/

Or alternatively:

root@hp-elitebook-840-g1--s0-v1:~# vi /etc/profile

...

export PATH=/tool/node-v4.2.4-linux-x64/bin:$PATH

...

Installing new version of Node.js

The same steps as mentioned above can be performed and the /etc/profile needs to be update to point to the new path (alternatively the following approach can be used to support multiple Node.js versions: https://nodecasts.io/update-node-js/ )





Updating npm



Node comes with npm installed so you should have a version of npm. However, npm gets updated more frequently than Node does, so you'll want to make sure it's the latest version.





Test: Run npm -v. The version should be higher than 2.1.8.

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v1:/tool/node-v4.2.4-linux-x64/bin$ ./npm -v

2.14.12

The current stable version of npm is 3.5.2

To upgrade, run: [sudo] npm install npm@latest -g



raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v1:/tool/node-v4.2.4-linux-x64/bin$ ./npm install npm@latest -g

/tool/node-v4.2.4-linux-x64/bin/npm -> /tool/node-v4.2.4-linux-x64/lib/node_modules/npm/bin/npm-cli.js

npm@3.5.2 /tool/node-v4.2.4-linux-x64/lib/node_modules/npm



And then everything looks fine (but you first need to log-out-log-in or restart in order that the changes in profile are picked up!):

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v1:~$ node -v

v4.2.4

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v1:~$ npm -v

3.5.2



3.3. Setup

Once the local/custom registry is set up – see chapter 5.2 - point yarn to local/custom registry (https://github.com/yarnpkg/yarn/issues/606):

npm config set registry http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-2-v3-0--npm-group



raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:~$ npm config set registry http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-2-v3-0--npm-group



Double check your local “.yarnrc” file to make sure everything worked fine:

vi .npmrc

...

registry=http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-2-v3-0--npm-group

...





3.4. npm install

https://docs.npmjs.com/getting-started/installing-npm-packages-locally

There are two ways to install npm packages: locally or globally. You choose which kind of installation to use based on how you want to use the package.



If you want to depend on the package from your own module using something like Node.js' require, then you want to install locally, which is npm install's default behavior. On the other hand, if you want to use it as a command line tool, something like the grunt CLI, then you want to install it globally.

http://stackoverflow.com/questions/5926672/where-does-npm-install-packages

Global libraries



You can run npm list -g to see where global libraries are installed.



On Unix systems they are normally placed in /usr/local/lib/node or /usr/local/lib/node_modules when installed globally. If you set the NODE_PATH environment variable to this path, the modules can be found by node.



Windows XP - %USERPROFILE%\Application Data\npm\node_modules

Windows 7 - %AppData%\npm\node_modules



Non-global libraries



Non-global libraries are installed the node_modules sub folder in the folder you are currently in.



You can run npm list to see the installed non-global libraries for your current location.

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:~$ npm list -g

/media/disk-ssd--s0-v1/tool/node-v4.2.4-linux-x64/lib

└─┬ npm@3.5.2

├── abbrev@1.0.7

├── ansi-regex@2.0.0

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:~$ npm –help

npm@3.5.2 /media/disk-ssd--s0-v1/tool/node-v4.2.4-linux-x64/lib/node_modules/npm

...





3.5. Directory Structure

For now and for npm modules I go with a very simple directory structure: “src” and “test” as follows:






3.6. Documentation

3.6.1. API Reference

http://usejsdoc.org/

/**

* This class is an extension of the standard {@link RegExp} class adding missing functionality.

* For further descriptions see the corresponding overridden methods.

* @param {string|RegExp} [pattern]

* @param {string} [options]

* @constructor

* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

* @see http://www.ecma-international.org/ecma-262/6.0/#sec-regexp-regular-expression-objects

*/

function Regex(pattern, options) {

/**

* Based on {@link RegExp#exec} but instead of simply getting "index" in the return which only tells the starting of

* the first group (0 group) we are getting "index[0..n]" which tells us the starting index of each matching group.

* @param {string} [str]

* @return {Object} {string[0..n], index:number[0..n], input:string}

* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec

*/

Regex.prototype.exec = function (str) {



3.6.1.1. Modify Home Text

http://stackoverflow.com/questions/30716438/default-home-text-and-content-for-jsdoc

  1. Create directory “template” in module root folder (e.g. “/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib/template”)

  2. Copy directory “node_modules/jsdoc/templates/default” to “template”

  3. Edit “template/default/publish.js

Replace:

generate('Home',

packages.concat(

[{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}]

).concat(files),

indexUrl);

With:

generate('<a href="http://www--s0-v1.becke.ch/tool/becke-ch--regex--s0-v1/becke-ch--regex--s0-0-v1--homepage--pl--client/" style="font-family: Neuropol; font-size: 50pt">becke.ch</a>',

packages.concat(

[{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}]

).concat(files),

indexUrl);

Pro: We now have the correct header, font and hyperlink!

Cons: The whole URL is as well put in the window title :-(




  1. From directory “data/becke-ch--style--s0-v1/font” copy the fonts: neuropol-webfont.eot, neuropol-webfont.ttf and neuropol-webfont.woff to directory “template/default/static/fonts

  2. Edit “template/default/static/styles/jsdoc-default.css

Insert on top the following font definition:

@font-face {

font-family: 'Neuropol';

src: url('../fonts/neuropol-webfont.eot?') format('eot'), url('../fonts/neuropol-webfont.woff') format('woff'), url('../fonts/neuropol-webfont.ttf') format('truetype');

}



3.6.1.2. Change method name (aliasing)

The following JSDoc:

/**

* Simply invokes the inherited method {@linkcode RegExp[Symbol.search]}.

* @param {string} str

* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@search

* @see http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype-@@search

*/

Regex.prototype[Symbol.search] = function (str) {

Will produce the following result:




This is a problem because [undefined] does not tell us which function we are looking at!

To fix this put an alias for the function name:

/**

* Simply invokes the inherited method {@linkcode RegExp[Symbol.search]}.

* @param {string} str

* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@search

* @see http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype-@@search

* @alias Regex.search

*/

Regex.prototype[Symbol.search] = function (str) {

And now the result looks as follows:




At least we know which function we are looking at. The only cons here is that there is (static) written in front of the function name which is not correct.



3.6.1.3. Intellij

https://www.jetbrains.com/help/idea/2017.1/creating-documentation-comments.html

  1. Place the caret before the declaration.

  2. Type the opening block comment /**, and press Enter.

  3. Add meaningful description of parameters and return values.



3.6.1.4. NPM

https://www.npmjs.com/package/jsdoc

package.json

"scripts": {

"build": "jsdoc src -d doc -R README.md"

},

"devDependencies": {

...

"jsdoc": "latest"

}

Installation:

npm install

Generate:

npm run build



raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib$ npm run build



> becke-ch--regex--s0-0-v1--base--pl--lib@1.0.20 build /media/disk-ssd--s0-v1/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib

> jsdoc src -d doc



3.6.2. README.md

https://gist.github.com/jxson/1784669#file-readme-md

3.6.2.1. Command Line & NPM

http://usejsdoc.org/about-including-readme.html

package.json

"scripts": {

"build": "jsdoc src -d doc -R README.md"

},

"devDependencies": {

...

"jsdoc": "latest"

}





3.7. Unit Testing

https://mochajs.org/

https://glebbahmutov.com/blog/unit-test-node-code-in-10-seconds/

https://semaphoreci.com/community/tutorials/getting-started-with-node-js-and-mocha



  1. Edit the current package.json file and add the following development dependency:

{

"name": "becke-ch--regex--s0-0-v1--base--pl--lib",

"version": "1.0.0",

"description": "Extension of JavaScript RegExp adding missing functionality",

"keywords": ["Regular Expression", "RegExp", "Regex", "exec"],

"main": "./src/becke-ch--regex--s0-0-v1--base--pl--lib.js",

"repository": {

"url": "file:///ws/tool/becke-ch--regex--s0-v1",

"type": "git"

},

"author": "Raoul Becke <regex--s0-v1@becke.ch> (http://becke.ch/tool/becke-ch--regex--s0-v1/)",

"license": "SEE LICENSE IN LICENSE",

"publishConfig": {

"registry": "http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted/"

},

"files": [

"./src"

],

"devDependencies": {

"mocha": "^3.2.0"

}

}

  1. run “yarn” (or “npm install”) to download and install the package

Alternatively you can install the module from the command line:

npm install --save-dev mocha

  1. Change into the test directory: “cd test” and run “../node_modules/mocha/bin/mocha becke-ch--regex--s0-0-v1--base--pl--lib--test.js”

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib/test$ ../node_modules/mocha/bin/mocha becke-ch--regex--s0-0-v1--base--pl--lib--test.js





exec

✓ regex abcdef applied on abcdef

✓ regex abcdef applied on 00abcdef

52 passing (18ms)



3.7.1. Assertions

Mocha allows you to use any assertion library you wish. Currently, we’re using Node.js’ built-in assert module:

var assert = require('assert');

var Regex = require('../src/becke-ch--regex--s0-0-v1--base--pl--lib');

describe('exec', function () {

it('regex abcdef applied on abcdef', function () {

var pattern = 'abcdef';

var str = 'abcdef';

var regex = new Regex(pattern);

var result = regex.exec(str);

var regexp = new RegExp(pattern);

var resultp = regexp.exec(str);

//console.log(result);

assert.equal(resultp.length, result.length);

assert.equal(resultp.input, result.input);

for (var i = 0; i < resultp.length; i++) {

assert.equal(resultp[i], result[i]);

}

assert.equal(1, result.index.length);

assert.equal(0, result.index[0]);

});

});





3.8. IntelliJ

After the steps above haven been performed and once NPM and Node.js are on the PATH, IntelliJ IDEA discovers them automatically and the user can go ahead creating a “Node.js and NPM” Project/Module - see IntelliJ Documentation.



3.8.1. Intellij Settings

in File | Settings | Languages & Frameworks | Node.js and NPM, press ellipsis button next to 'Node interpreter' field

in Node.js Interpreters dialog that opens, open 'Node Interpreter' dropdown, choose latest node interpreter






3.9. Workflow

https://docs.npmjs.com/getting-started/creating-node-modules#

3.9.1. package.json

https://docs.npmjs.com/files/package.json

name

The most important things in your package.json are the name and version fields. Those are actually required, and your package won't install without them. The name and version together form an identifier that is assumed to be completely unique.

Some rules:

The name must be less than or equal to 214 characters. This includes the scope for scoped packages.

The name can't start with a dot or an underscore.

New packages must not have uppercase letters in the name.

The name ends up being part of a URL, an argument on the command line, and a folder name. Therefore, the name can't contain any non-URL-safe characters.

A name can be optionally prefixed by a scope, e.g. @myorg/mypackage. See npm-scope for more detail.

Npm-scope, Scoped packages

All npm packages have a name. Some package names also have a scope. A scope follows the usual rules for package names (url-safe characters, no leading dots or underscores). When used in package names, preceded by an @-symbol and followed by a slash, e.g.

@somescope/somepackagename

Installing scoped packages

Scoped packages are installed to a sub-folder of the regular installation folder, e.g. if your other packages are installed in node_modules/packagename, scoped modules will be in node_modules/@myorg/packagename.



npm install:

npm install @myorg/mypackage

Or in package.json:

"dependencies": {

"@myorg/mypackage": "^1.3.0"

}



Actually I prefer to have the organization as part of the name (becke-ch--regex--s0-0-v1--base--pl--lib) and not working with scoped packages because this is more portable when moving away from npm or simply working on javascript files!





description

Put a description in it. It's a string. This helps people discover your package, as it's listed in npm search.



keywords

Put keywords in it. It's an array of strings. This helps people discover your package as it's listed in npm search.



homepage

The url to the project homepage.



bugs

The url to your project's issue tracker and / or the email address to which issues should be reported.

{ "url" : "https://github.com/owner/project/issues"

, "email" : "project@hostname.com"

}



license

You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you're placing on it.

https://spdx.org/licenses/

{ "license" : "(ISC OR GPL-3.0)" }

If you are using a license that hasn't been assigned an SPDX identifier, or if you are using a custom license, use a string value like this one:

{ "license" : "SEE LICENSE IN <filename>" }

Then include a file named <filename> at the top level of the package.

Finally, if you do not wish to grant others the right to use a private or unpublished package under any terms:

{ "license": "UNLICENSED"}



people fields: author, contributors

The "author" is one person. "contributors" is an array of people. A "person" is an object with a "name" field and optionally "url" and "email", like this:

{ "name" : "Barney Rubble"

, "email" : "b@rubble.com"

, "url" : "http://barnyrubble.tumblr.com/"

}



files

The "files" field is an array of files to include in your project.

You can also provide a ".npmignore" file in the root of your package or in subdirectories, which will keep files from being included, even if they would be picked up by the files array. The .npmignore file works just like a .gitignore.

Certain files are always included, regardless of settings:

package.json

README (and its variants)

CHANGELOG (and its variants)

LICENSE / LICENCE



repository

Specify the place where your code lives. This is helpful for people who want to contribute. If the git repo is on GitHub, then the npm docs command will be able to find you.

Do it like this:

"repository" :

{ "type" : "git"

, "url" : "https://github.com/npm/npm.git"

}



"repository" :

{ "type" : "svn"

, "url" : "https://v8.googlecode.com/svn/trunk/"

}

Private modules respective source code that should not (yet) be published public should point to the local code repository as follows:

"repository": {"url":"file:///ws/tool/becke-ch--regex--s0-v1","type":"git"},

Once the module is published public a next step could be to publish as well the source code public.

http://stackoverflow.com/questions/18128863/should-node-modules-folder-be-included-in-the-git-repository

Imagine that you have just finished enterprise app and you will have to support it for 3-5 years. You definitely don't want to depend on someone's npm module which can tomorrow disappear and you can't update your app anymore.



Or you have your private modules which are not accessible from internet and you can't build your app on Internet. Or maybe you don't want to depend with your final build on npm service for some reasons.



You can find pros and cons in this Addy Osmani article (although it is about Bower, it is almost the same situation). And I will end with quote from Bower homepage and Addy's article:



“If you aren’t authoring a package that is intended to be consumed by others (e.g., you’re building a web app), you should always check installed packages into source control.”

I would recommend against checking in node_modules because of packages like PhantomJS and node-sass for example, which install the appropriate binary for the current system.



This means that if one Dev runs npm install on Linux and checks in node_modules – it won't work for another Dev who clones the repo on Windows.

...





dependencies

Dependencies are specified in a simple object that maps a package name to a version range.

{ "dependencies" :

{ "foo" : "1.0.0 - 2.9999.9999"

, "bar" : ">=1.0.2 <2.1.2"

, "baz" : ">1.0.2 <=2.3.4"

, "boo" : "2.0.1"

, "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"

, "asd" : "http://asdf.com/asdf.tar.gz"

, "til" : "~1.2"

, "elf" : "~1.2.3"

, "two" : "2.x"

, "thr" : "3.3.x"

, "lat" : "latest"

, "dyl" : "file:../dyl"

}

}



URLs as Dependencies

You may specify a tarball URL in place of a version range.



devDependencies

If someone is planning on downloading and using your module in their program, then they probably don't want or need to download and build the external test or documentation framework that you use.



peerDependencies

In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a require of this host.



bundledDependencies

Array of package names that will be bundled when publishing the package.



optionalDependencies

If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the optionalDependencies object.



engines

You can specify the version of node that your stuff works on:

{ "engines" : { "node" : ">=0.10.3 <0.12" } }



os

You can specify which operating systems your module will run on:

"os" : [ "darwin", "linux" ]



cpu

If your code only runs on certain cpu architectures, you can specify which ones.

"cpu" : [ "x64", "ia32" ]



preferGlobal

If your package is primarily a command-line application that should be installed globally, then set this value to true to provide a warning if it is installed locally.



private

If you set "private": true in your package.json, then npm will refuse to publish it.



publishConfig

This is a set of config values that will be used at publish-time. It's especially handy if you want to set the tag, registry or access, so that you can ensure that a given package is not tagged with "latest", published to the global public registry or that a scoped module is private by default.

Any config values can be overridden, but of course only "tag", "registry" and "access" probably matter for the purposes of publishing.

registry

Default: https://registry.npmjs.org/

Type: url

The base URL of the npm package registry.



Private modules respective modules that should not (yet) be published public I would point to the local repository as follows:

"publishConfig" : {

"registry" : "http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted/"

}







OPTIONAL

main

The main field is a module ID that is the primary entry point to your program.



bin

A lot of packages have one or more executable files that they'd like to install into the PATH.



man

Specify either a single file or an array of filenames to put in place for the man program to find.



directories

The CommonJS Packages spec details a few ways that you can indicate the structure of your package using a directories object.



scripts

The "scripts" property is a dictionary containing script commands that are run at various times in the lifecycle of your package.



config

A "config" object can be used to set configuration parameters used in package scripts that persist across upgrades.



...



3.9.2. Create a new Node.js module

https://docs.npmjs.com/getting-started/creating-node-modules

npm init



raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib$ npm init

This utility will walk you through creating a package.json file.

It only covers the most common items, and tries to guess sensible defaults.



See `npm help json` for definitive documentation on these fields

and exactly what they do.



Use `npm install <pkg> --save` afterwards to install a package and

save it as a dependency in the package.json file.



Press ^C at any time to quit.

name: (becke-ch--regex--s0-0-v1--base--pl--lib)

version: (1.0.0)

description: Extension of JavaScript RegExp adding missing functionality

entry point: (index.js)

test command:

git repository:

keywords: Regular Expression, RegExp, Regex, exec

author: Raoul Becke <regex--s0-v1@becke.ch> (http://becke.ch/tool/becke-ch--regex--s0-v1/)

license: (ISC) SEE LICENSE IN LICENSE



About to write to /media/disk-ssd--s0-v1/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v2--base--pl--lib/package.json:



{

"name": "becke-ch--regex--s0-0-v1--base--pl--lib",

"version": "1.0.0",

"description": "Extension of JavaScript RegExp adding missing functionality",

"main": "index.js",

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1"

},

"keywords": [

"Regular",

"Expression",

"RegExp",

"Regex",

"exec"

],

"author": "Raoul Becke <regex--s0-v1@becke.ch> (http://becke.ch/tool/becke-ch--regex--s0-v1/)",

"license": "SEE LICENSE IN LICENSE"

}





Is this ok? (yes) yes



Adapt & extend the missing properties:

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib$ vi package.json



{

"name": "becke-ch--regex--s0-0-v1--base--pl--lib",

"version": "1.0.0",

"description": "Extension of JavaScript RegExp adding missing functionality",

"main": "index.js",

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1"

},

"keywords": [

"Regular",

"Expression",

"RegExp",

"Regex",

"exec"

],

"repository": "file:///ws/tool/becke-ch--regex--s0-v1",

"repository": {"url":"file:///ws/tool/becke-ch--regex--s0-v1","type":"git"},

"author": "Raoul Becke <regex--s0-v1@becke.ch> (http://becke.ch/tool/becke-ch--regex--s0-v1/)",

"license": "SEE LICENSE IN becke-ch—regex--s0-v1--license.txt"

"publishConfig" : {

"registry" : "http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted/"

}

}



3.9.2.1. Intellij – option a) new (npm) module from existing sources

Creating a new npm module from scratch is not well supported respective see https://intellij-support.jetbrains.com/hc/requests/907710 : “When going to "New Module", selecting "Node.js and NPM" I only have the choice "Node.js Express App" and when I choose that I get a lot of node-modules downloaded and "dependencies" that I don't need

Therefore there are 2 possibilities:

  1. File → New Module → From Existing Sources …

  2. Select the directory where you invoked previously “yarn init” e.g. /ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib








  1. Select “Create module from existing sources”




  1. Source files for project have been found. Leave default which is all directories selected.






  1. No Frameworks detected. Click Finish.






3.9.2.2. Intellij – option b) new (npm) module from static we

This is an alternative installation procedure which actually brings no additional benefit. There exists currently no option to create an empty/minimal npm module:

  1. Select “Static Web”

  2. Select “Static Web”








  1. Enter module name: becke-ch--<element>--sX-Y-vZ--<UseCase>--pl--client|clientlib|server|serverlib|lib (e.g. becke-ch--regex--s0-0-v1--base--pl--lib)




  1. And finally go into this new empty directory and create a new npm-/yarn-module as described above



3.9.3. Publishing a package

https://docs.npmjs.com/getting-started/publishing-npm-packages

3.9.3.1. Create an NPM account (optional)

This step is only required when publishing to central NPM repository:

Create an NPM Account: https://www.npmjs.com/signup

Create an NPM Account: https://www.npmjs.com/signup

Alternatively you can create a user with:

npm adduser

Alternatively you can create a user with:

npm adduser

Adding user to default repository:

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib$ npm adduser

Username: becke-ch--npm--s0-v1

Password:

Email: (this IS public) npm--s0-v1@becke.ch

Logged in as becke-ch--npm--s0-v1 on http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-2-v3-0--npm-group.

Adding user to private repository: http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted

npm adduser --registry=http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib$ npm adduser --registry=http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted

Username: becke-ch--npm--s0-v1

Password:

Email: (this IS public) npm--s0-v1@becke.ch

Logged in as becke-ch--npm--s0-v1 on http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted.



3.9.3.2. Logging into npm (optional)

This step is only required when publishing to central NPM repository:

If you created a user on the web-site, use npm login to store the credentials on the client:

npm login



3.9.3.3. Logging into nexus – authentication

Make sure you created a user – see chapter: 5.2.8.1.

https://books.sonatype.com/nexus-book/reference/npm-deploying-packages.html

Since the .npmrc file usually contains a registry value intended only for getting new packages, a simple way to override this value is to provide a registry to the publish command:

npm publish --registry http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted/

Alternately, you can edit your package.json file and add a publishConfig section:

vi package.json

"publishConfig": {

"registry": "http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted/"

},

...

Publishing requires authentication. It can be configured by adding an _auth value to .npmrc. The value has to be generated by base64-encoding the string of username:password. You can create this encoded string with the command line call openssl e.g.: for the default admin user:

echo -n 'admin:admin123' | openssl base64



echo -n 'becke-ch--npm--s0-v1:y...' | openssl base64

After this the base64 encoded credentials can be found in between the begin and end certificate lines in the output file:

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:~$ echo -n 'admin:admin123' | openssl base64

YWRtaW46YWRtaW4xMjM=



raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/download/becke-ch--repo-nexus--s1-0-v3/log$ echo -n 'becke-ch--npm--s0-v1:y...' | openssl base64

YmVja2UtY2gtLW5wbS0tczAtdjE6eXMxNTExNjI=

Once you have the encoded credentials the value as well as author information can then be added to the .npmrc file:

vi .npmrc

#registry=http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-2-v3-0--npm-group

init.author.name = becke.ch

init.author.email = npm--s0-v1@becke.ch

init.author.url = http://becke.ch

# an email is required to publish npm packages

email=npm--s0-v1@becke.ch

always-auth=true

_auth=YmVja2UtY2gtLW5wbS0tczAtdjE6eXMxNTExNjI=







3.9.3.4. Publishing the package

Use npm publish to publish the package.

Note that everything in the directory will be included unless it is ignored by a local .gitignore or .npmignore file as described in npm-developers.

Also make sure there isn't already a package with the same name, owned by somebody else.

npm publish



raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib$ npm publish

+ becke-ch--regex--s0-0-v1--base--pl--lib@1.0.15

Once a package is published to the private registry in the repository manager, any other developers or build servers, that access it via the repository group have instant access to the packages.



3.9.3.4.1. ERROR

ERROR: npm ERR! need auth You need to authorize this machine using `npm adduser`

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib$ npm publish

npm ERR! Linux 4.9.0-040900-generic

npm ERR! argv "/media/disk-ssd--s0-v1/tool/node-v6.10.1-linux-x64/bin/node" "/tool/node-v6.10.1-linux-x64/bin/npm" "publish"

npm ERR! node v6.10.1

npm ERR! npm v3.10.10

npm ERR! code ENEEDAUTH



npm ERR! need auth auth required for publishing

npm ERR! need auth You need to authorize this machine using `npm adduser`



npm ERR! Please include the following file with any support request:

npm ERR! /media/disk-ssd--s0-v1/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib/npm-debug.log

SOLUTION: https://books.sonatype.com/nexus-book/reference/npm-deploying-packages.html

See chapter: 3.9.3.3 and 3.9.3.4



ERROR: npm ERR! publish Failed PUT 400

raoul-becke--s0-v1@hp-elitebook-840-g1--s0-v3:/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib$ npm publish

npm ERR! publish Failed PUT 400

npm ERR! Linux 4.9.0-040900-generic

npm ERR! argv "/media/disk-ssd--s0-v1/tool/node-v6.10.1-linux-x64/bin/node" "/tool/node-v6.10.1-linux-x64/bin/npm" "publish"

npm ERR! node v6.10.1

npm ERR! npm v3.10.10

npm ERR! code E400



npm ERR! Repository does not allow updating assets: becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted : repository

npm ERR!

npm ERR! If you need help, you may report this error at:

npm ERR! <https://github.com/npm/npm/issues>



npm ERR! Please include the following file with any support request:

npm ERR! /media/disk-ssd—s0-v1/ws/tool/becke-ch--regex--s0-v1/intellij/becke-ch--regex--s0-0-v1--base--pl--lib/npm-debug.log

When consulting the nexus trace log:

2017-04-12 15:53:56,688+0200 WARN [qtp2010031162-54] becke-ch--npm--s0-v1 com.sonatype.nexus.repository.npm.internal.NpmHandlers - Error: PUT /becke-ch--regex--s0-0-v1--base--pl--lib: Status{successful=false, code=400, message='null'} - Repository does not allow updating assets: becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted

org.sonatype.nexus.repository.IllegalOperationException: Repository does not allow updating assets: becke-ch--repo-nexus--s1-0-1-v3-0--npm-hosted

at org.sonatype.nexus.repository.storage.StorageTxImpl.attachBlob(StorageTxImpl.java:622) [org.sonatype.nexus.repository:3.2.1.01]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [na:1.8.0_92]

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [na:1.8.0_92]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [na:1.8.0_92]

at java.lang.reflect.Method.invoke(Method.java:498) [na:1.8.0_92]

at org.sonatype.nexus.common.stateguard.SimpleMethodInvocation.proceed(SimpleMethodInvocation.java:53) [org.sonatype.nexus.common:3.2.1.01]

...

SOLUTION: The version number needs to be incremented:

package.json:

"version": "1.0.21",



3.9.3.5. Deleting a published package (nexus repository)

In the NPM repository a package can only be deprecated: https://docs.npmjs.com/cli/deprecate

To delete a package in the nexus repository:

  1. Go to “Browse → Components” and select the repository where the component should be deleted (e.g. “http://localhost:8081/repository/becke-ch--repo-nexus--s1-0-2-v3-0--npm-hosted”):






  1. Select the component in the version that should get deleted (e.g. name: “becke-ch—regex--s0-0-v1--base--pl--lib” & version: “1.0.15”):




  1. And click “Delete Component”: