├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── documentation ├── 0000-template │ └── article.md ├── 0001-node-introduction │ ├── async.png │ ├── fast.png │ └── index.md ├── 0002-node-history │ └── index.md ├── 0003-node-installation │ └── index.md ├── 0004-node-javascript-language │ └── index.md ├── 0005-node-difference-browser │ └── index.md ├── 0006-v8 │ └── index.md ├── 0007-node-run-cli │ └── index.md ├── 0008-node-terminate-program │ └── index.md ├── 0009-node-environment-variables │ └── index.md ├── 0010-node-hosting │ └── index.md ├── 0011-node-repl │ ├── globals.png │ ├── index.md │ └── tab.png ├── 0012-node-cli-args │ └── index.md ├── 0013-node-output-to-cli │ └── index.md ├── 0014-node-input-from-cli │ └── index.md ├── 0015-node-export-module │ └── index.md ├── 0016-npm │ └── index.md ├── 0017-where-npm-install-packages │ └── index.md ├── 0018-how-to-use-npm-package │ ├── binary-files.png │ ├── cow-say.png │ ├── index.md │ └── node_modules-content.png ├── 0019-package-json │ └── index.md ├── 0020-package-lock-json │ └── index.md ├── 0021-npm-know-version-installed │ └── index.md ├── 0022-npm-install-previous-package-version │ └── index.md ├── 0023-update-npm-dependencies │ ├── index.md │ ├── outdated-packages.png │ └── updated-packages.png ├── 0024-npm-semantic-versioning │ └── index.md ├── 0025-npm-uninstall-packages │ └── index.md ├── 0026-npm-packages-local-global │ └── index.md ├── 0027-npm-dependencies-devdependencies │ └── index.md ├── 0028-npx │ └── index.md ├── 0029-node-event-loop │ ├── call-stack-first-example.png │ ├── call-stack-second-example.png │ ├── exception-call-stack.png │ ├── execution-order-first-example.png │ ├── execution-order-second-example.png │ └── index.md ├── 0030-node-process-nexttick │ └── index.md ├── 0031-node-setimmediate │ └── index.md ├── 0032-javascript-timers │ ├── index.md │ ├── recursive-settimeout.png │ ├── setinterval-ok.png │ ├── setinterval-overlapping.png │ └── setinterval-varying-duration.png ├── 0033-javascript-callbacks │ └── index.md ├── 0034-javascript-promises │ └── index.md ├── 0035-javascript-async-await │ └── index.md ├── 0036-node-event-emitter │ └── index.md ├── 0037-node-http-server │ └── index.md ├── 0038-node-make-http-requests │ └── index.md ├── 0039-node-http-post │ └── index.md ├── 0040a-node-request-data │ └── index.md ├── 0040b-node-file-descriptors │ └── index.md ├── 0041-node-file-stats │ └── index.md ├── 0042-node-file-paths │ └── index.md ├── 0043-node-reading-files │ └── index.md ├── 0044-node-writing-files │ └── index.md ├── 0045-node-folders │ └── index.md ├── 0046-node-module-fs │ └── index.md ├── 0047-node-module-path │ └── index.md ├── 0048-node-module-os │ └── index.md ├── 0049-node-module-events │ └── index.md ├── 0050-node-module-http │ └── index.md ├── 0051-node-buffers │ └── index.md ├── 0052-nodejs-streams │ └── index.md ├── 0053-node-difference-dev-prod │ └── index.md ├── 0054-node-exceptions │ └── index.md ├── 0055-node-inspect-object │ ├── console-log-browser-expanded.png │ ├── console-log-browser.png │ └── index.md └── README.md ├── meetings ├── 2018-02-01.md ├── 2018-02-15.md ├── 2018-03-01.md ├── 2018-03-15.md ├── 2018-03-29.md ├── 2018-04-12.md ├── 2018-04-26.md ├── 2018-05-10.md ├── 2018-05-24.md ├── 2018-05-31.md ├── 2018-09-13.md ├── 2018-09-27.md ├── 2018-1-17.md ├── 2018-10-13.md ├── 2018-12-06.md ├── 2019-02-28.md ├── 2019-03-14.md ├── 2019-03-28.md ├── 2019-04-25.md └── 2019-06-06.md └── style-guide └── 0001-voice-and-tone.md /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .env 4 | thumbs.db 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Website Redesign 2 | 3 | This is an adapted version of the contributing guide used by the Community Committee: https://github.com/nodejs/community-committee/blob/master/CONTRIBUTING.md 4 | 5 | ## Vocabulary 6 | 7 | * A **Contributor** is any individual creating or commenting on an issue or pull request, 8 | or contributing in some other way. 9 | * A **Collaborator** is a contributor who has been given write access to the repository. 10 | 11 | ## Contributing Documentation and Getting Started Guides 12 | 13 | While the Website Redesign working group continues to iterate on site design and content structure, we will use an RFC process to accept and evaluate Node.js documentation contributions in this repo. All proposed documentation pages and instructions for the RFC process can be found in the [/documentation](./documentation) directory. 14 | 15 | ## All Other Contributions 16 | 17 | Any change to resources in this repository must be through pull requests. This applies to all changes to documentation, code, binary files, etc. No pull request can be merged without being reviewed. 18 | 19 | The default for each contribution is that it is accepted once no collaborator has an objection. During review collaborators may also request that a specific contributor who is most versed in a particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off" process for contributions to land. Once all issues brought by collaborators are addressed it can be landed by any collaborator. 20 | 21 | In the case of an objection being raised in a pull request by another collaborator, all involved collaborators should seek to arrive at a consensus by way of addressing concerns being expressed by discussion, compromise on the proposed change, or withdrawal of the proposed change. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The original contents of the nodejs.org repo are licensed for use as follows: 2 | 3 | """ 4 | Copyright Node.js Website WG contributors. All rights reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to 8 | deal in the Software without restriction, including without limitation the 9 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | sell copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | IN THE SOFTWARE. 23 | """ 24 | -------------------------------------------------------------------------------- /documentation/0000-template/article.md: -------------------------------------------------------------------------------- 1 | - **Start Date:** (fill me in with today's date, YYYY-MM-DD) 2 | - **PR:** (leave this empty) 3 | - **Issue:** [#0000](link-to-issue) (remove if no associated issue) 4 | - **Keywords:** (4-8 keywords for page meta data) 5 | - **Summary:** (~60 character explanation of the article content for page meta data) 6 | 7 | # Title 8 | 9 | > Introduction paragraph(s). 10 | 11 | ## Body Content 12 | 13 | > Body content, including sub-headings (H3 or lower, using the appropriate H(n) level for the content's place in the document), prose, code samples, screenshots, etc. 14 | 15 | > Note: any included screenshots for your article should be saved in the same directory your article.md lives in! 16 | 17 | ## Conclusion 18 | 19 | > 1-2 paragraphs wrapping up the article 20 | -------------------------------------------------------------------------------- /documentation/0001-node-introduction/async.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0001-node-introduction/async.png -------------------------------------------------------------------------------- /documentation/0001-node-introduction/fast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0001-node-introduction/fast.png -------------------------------------------------------------------------------- /documentation/0002-node-history/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: A brief history of Node.js 3 | description: 'A look back on the history of Node.js from 2009 to today' 4 | author: flaviocopes 5 | --- 6 | 7 | Believe it or not, Node.js is just 9 years old. 8 | 9 | In comparison, JavaScript is 23 years old and the web as we know it (after the introduction of Mosaic) is 25 years old. 10 | 11 | 9 years is such a little amount of time for a technology, but Node.js seems to have been around forever. 12 | 13 | I've had the pleasure to work with Node since the early days when it was just 2 years old, and despite the little information available, you could already feel it was a huge thing. 14 | 15 | In this post, we want to draw the big picture of Node in its history, to put things in perspective. 16 | 17 | 18 | 19 | - [A little bit of history](#a-little-bit-of-history) 20 | - [2009](#2009) 21 | - [2010](#2010) 22 | - [2011](#2011) 23 | - [2012](#2012) 24 | - [2013](#2013) 25 | - [2014](#2014) 26 | - [2015](#2015) 27 | - [2016](#2016) 28 | - [2017](#2017) 29 | - [2018](#2018) 30 | 31 | 32 | 33 | ## A little bit of history 34 | 35 | JavaScript is a programming language that was created at Netscape as a scripting tool to manipulate web pages inside their browser, [Netscape Navigator](https://en.wikipedia.org/wiki/Netscape_Navigator). 36 | 37 | Part of the business model of Netscape was to sell Web Servers, which included an environment called _Netscape LiveWire_, which could create dynamic pages using server-side JavaScript. So the idea of server-side JavaScript was not introduced by Node.js, but it's old just like JavaScript - but at the time it was not successful. 38 | 39 | One key factor that led to the rise of Node.js was timing. JavaScript since a few years was starting being considered a serious language, thanks for the "Web 2.0" applications that showed the world what a modern experience on the web could be like (think Google Maps or GMail). 40 | 41 | The JavaScript engines performance bar raised considerably thanks to the browser competition battle, which is still going strong. Development teams behind each major browser work hard every day to give us better performance, which is a huge win for JavaScript as a platform. V8, the engine that Node.js uses under the hood, is one of those and in particular it's the Chrome JS engine. 42 | 43 | But of course, Node.js is not popular just because of pure luck or timing. It introduced much innovative thinking on how to program in JavaScript on the server. 44 | 45 | ## 2009 46 | 47 | Node.js is born 48 | The first form of npm is created 49 | 50 | ## 2010 51 | 52 | Express is born 53 | [Socket.io](https://socket.io) is born 54 | 55 | ## 2011 56 | 57 | npm hits 1.0 58 | Big companies start adopting Node: LinkedIn, Uber 59 | [Hapi](https://hapijs.com) is born 60 | 61 | ## 2012 62 | 63 | Adoption continues very rapidly 64 | 65 | ## 2013 66 | 67 | First big blogging platform using Node: Ghost 68 | [Koa](https://koajs.com/) is born 69 | 70 | ## 2014 71 | 72 | The Big Fork: [io.js](https://iojs.org/) is a major fork of Node.js, with the goal of introducing ES6 support and moving faster 73 | 74 | ## 2015 75 | 76 | The [Node.js Foundation](https://foundation.nodejs.org/) is born 77 | IO.js is merged back into Node.js 78 | npm introduces private modules 79 | Node 4 (no 1, 2, 3 versions were previously released) 80 | 81 | ## 2016 82 | 83 | The [leftpad incident](https://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm) 84 | Yarn is born 85 | Node 6 86 | 87 | ## 2017 88 | 89 | npm focuses more on security 90 | Node 8 91 | HTTP/2 92 | V8 introduces Node in its testing suite, officially making Node a target for the JS engine, in addition to Chrome 93 | 3 billion npm downloads every week 94 | 95 | ## 2018 96 | 97 | Node 10 98 | ES modules .mjs experimental support 99 | -------------------------------------------------------------------------------- /documentation/0003-node-installation/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to install Node.js 3 | description: 'How you can install Node.js on your system: a package manager, the official website installer or nvm' 4 | author: flaviocopes 5 | --- 6 | 7 | Node.js can be installed in different ways. This post highlights the most common and convenient ones. 8 | 9 | Official packages for all the major platforms are available at . 10 | 11 | One very convenient way to install Node.js is through a package manager. In this case, every operating system has its own. 12 | 13 | On macOS, [Homebrew](https://brew.sh/) is the de-facto standard, and - once installed - allows to install Node.js very easily, by running this command in the CLI: 14 | 15 | ```sh 16 | brew install node 17 | ``` 18 | 19 | Other package managers for Linux and Windows are listed in 20 | 21 | `nvm` is a popular way to run Node. It allows you to easily switch the Node version, and install new versions to try and easily rollback if something breaks, for example. 22 | 23 | It is also very useful to test your code with old Node versions. 24 | 25 | See for more information about this option. 26 | 27 | My suggestion is to use the official installer if you are just starting out and you don't use Homebrew already, otherwise, Homebrew is my favorite solution. 28 | 29 | In any case, when Node is installed you'll have access to the `node` executable program in the command line. 30 | -------------------------------------------------------------------------------- /documentation/0004-node-javascript-language/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How much JavaScript do you need to know to use Node? 3 | description: 'If you are just starting out with JavaScript, how much deeply do you need to know the language?' 4 | author: flaviocopes 5 | --- 6 | 7 | As a beginner, it's hard to get to a point where you are confident enough in your programming abilities. 8 | 9 | While learning to code, you might also be confused at where does JavaScript end, and where Node.js begins, and vice versa. 10 | 11 | I would recommend you to have a good grasp of the main JavaScript concepts before diving into Node.js: 12 | 13 | - Lexical Structure 14 | - Expressions 15 | - Types 16 | - Variables 17 | - Functions 18 | - this 19 | - Arrow Functions 20 | - Loops 21 | - Loops and Scope 22 | - Arrays 23 | - Template Literals 24 | - Semicolons 25 | - Strict Mode 26 | - ECMAScript 6, 2016, 2017 27 | 28 | With those concepts in mind, you are well on your road to become a proficient JavaScript developer, in both the browser and in Node.js. 29 | 30 | The following concepts are also key to understand asynchronous programming, which is one fundamental part of Node.js: 31 | 32 | - Asynchronous programming and callbacks 33 | - Timers 34 | - Promises 35 | - Async and Await 36 | - Closures 37 | - The Event Loop 38 | -------------------------------------------------------------------------------- /documentation/0005-node-difference-browser/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Differences between Node and the Browser 3 | description: 'How writing JavaScript application in Node.js differs from programming for the Web inside the browser' 4 | author: flaviocopes 5 | --- 6 | 7 | Both the browser and Node use JavaScript as their programming language. 8 | 9 | Building apps that run in the browser is a completely different thing than building a Node.js application. 10 | 11 | Despite the fact that it's always JavaScript, there are some key differences that make the experience radically different. 12 | 13 | As a frontend developer who extensively uses Javascript, Node apps brings with it, a huge advantage - the comfort of programming everything, the frontend and the backend, in a single language 14 | 15 | You have a huge opportunity because we know how hard it is to fully, deeply learn a programming language, and by using the same language to perform all your work on the web - both on the client and on the server, you're in a unique position of advantage. 16 | 17 | What changes is the ecosystem. 18 | 19 | In the browser, most of the time what you are doing is interacting with the DOM, or other Web Platform APIs like Cookies. Those do not exist in Node, of course. You don't have the `document`, `window` and all the other objects that are provided by the browser. 20 | 21 | And in the browser, we don't have all the nice APIs that Node.js provides through its modules, like the filesystem access functionality. 22 | 23 | Another big difference is that in Node.js you control the environment. Unless you are building an open source application that anyone can deploy anywhere, you know which version of Node you will run the application on. Compared to the browser environment, where you don't get the luxury to choose what browser your visitors will use, this is very convenient. 24 | 25 | This means that you can write all the modern ES6-7-8-9 JavaScript that your Node version supports. 26 | 27 | Since JavaScript moves so fast, but browsers can be a bit slow and users a bit slow to upgrade, sometimes on the web, you are stuck to use older JavaScript / ECMAScript releases. 28 | 29 | You can use Babel to transform your code to be ES5-compatible before shipping it to the browser, but in Node, you won't need that. 30 | 31 | Another difference is that Node uses the CommonJS module system, while in the browser we are starting to see the ES Modules standard being implemented. 32 | 33 | In practice, this means that for the time being you use `require()` in Node and `import` in the browser. 34 | -------------------------------------------------------------------------------- /documentation/0006-v8/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The V8 JavaScript Engine 3 | description: "V8 is the name of the JavaScript engine that powers Google Chrome. It's the thing that takes our JavaScript and executes it while browsing with Chrome. V8 provides the runtime environment in which JavaScript executes. The DOM and the other Web Platform APIs are provided by the browser." 4 | author: flaviocopes 5 | --- 6 | 7 | V8 is the name of the JavaScript engine that powers Google Chrome. It's the thing that takes our JavaScript and executes it while browsing with Chrome. 8 | 9 | V8 provides the runtime environment in which JavaScript executes. The DOM, and the other Web Platform APIs are provided by the browser. 10 | 11 | The cool thing is that the JavaScript engine is independent by the browser in which it's hosted. This key feature enabled the rise of Node.js. V8 was chosen to be the engine that powered Node.js back in 2009, and as the popularity of Node.js exploded, V8 became the engine that now powers an incredible amount of server-side code written in JavaScript. 12 | 13 | The Node.js ecosystem is huge and thanks to it V8 also powers desktop apps, with projects like Electron. 14 | 15 | ## Other JS engines 16 | 17 | Other browsers have their own JavaScript engine: 18 | 19 | - Firefox has [**Spidermonkey**](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey) 20 | - Safari has **JavaScriptCore** (also called Nitro) 21 | - Edge has **Chakra** 22 | 23 | and many others exist as well. 24 | 25 | All those engines implement the ECMA ES-262 standard, also called ECMAScript, the standard used by JavaScript. 26 | 27 | ## The quest for performance 28 | 29 | V8 is written in C++, and it's continuously improved. It is portable and runs on Mac, Windows, Linux and several other systems. 30 | 31 | In this V8 introduction, we will ignore the implementation details of V8: they can be found on more authoritative sites (e.g. the V8 official site), and they change over time, often radically. 32 | 33 | V8 is always evolving, just like the other JavaScript engines around, to speed up the Web and the Node.js ecosystem. 34 | 35 | On the web, there is a race for performance that's been going on for years, and we (as users and developers) benefit a lot from this competition because we get faster and more optimized machines year after year. 36 | 37 | ## Compilation 38 | 39 | JavaScript is generally considered an interpreted language, but modern JavaScript engines no longer just interpret JavaScript, they compile it. 40 | 41 | This happens since 2009 when the SpiderMonkey JavaScript compiler was added to Firefox 3.5, and everyone followed this idea. 42 | 43 | JavScript is internally compiled by V8 with **just-in-time** (JIT) **compilation** to speed up the execution. 44 | 45 | This might seem counter-intuitive, but since the introduction of Google Maps in 2004, JavaScript has evolved from a language that was generally executing a few dozens of lines of code to complete applications with thousands to hundreds of thousands of lines running in the browser. 46 | 47 | Our applications now can run for hours inside a browser, rather than being just a few form validation rules or simple scripts. 48 | 49 | In this _new world_, compiling JavaScript makes perfect sense because while it might take a little bit more to have the JavaScript _ready_, once done it's going to be much more performant that purely interpreted code. 50 | -------------------------------------------------------------------------------- /documentation/0007-node-run-cli/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Run Node.js scripts from the command line 3 | description: 'How to run any Node.js script from the CLI' 4 | author: flaviocopes 5 | --- 6 | 7 | The usual way to run a Node program is to call the `node` globally available command (once you install Node) and pass the name of the file you want to execute. 8 | 9 | If your main Node application file is in `app.js`, you can call it by typing 10 | 11 | ```sh 12 | node app.js 13 | ``` 14 | -------------------------------------------------------------------------------- /documentation/0008-node-terminate-program/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to exit from a Node.js program 3 | description: 'Learn how to terminate a Node.js app in the best possible way' 4 | author: flaviocopes 5 | --- 6 | 7 | There are various ways to terminate a Node.js application. 8 | 9 | When running a program in the console you can close it with `ctrl-C`, but what we want to discuss here is programmatically exiting. 10 | 11 | Let's start with the most drastic one, and see why you're better off _not_ using it. 12 | 13 | The `process` core module is provides a handy method that allows you to programmatically exit from a Node.js program: `process.exit()`. 14 | 15 | When Node.js runs this line, the process is immediately forced to terminate. 16 | 17 | This means that any callback that's pending, any network request still being sent, any filesystem access, or processes writing to `stdout` or `stderr` - all is going to be ungracefully terminated right away. 18 | 19 | If this is fine for you, you can pass an integer that signals the operating system the exit code: 20 | 21 | ```js 22 | process.exit(1) 23 | ``` 24 | 25 | By default the exit code is `0`, which means success. Different exit codes have different meaning, which you might want to use in your own system to have the program communicate to other programs. 26 | 27 | You can read more on exit codes at 28 | 29 | You can also set the `process.exitCode` property: 30 | 31 | ```js 32 | process.exitCode = 1 33 | ``` 34 | 35 | and when the program will later end, Node will return that exit code. 36 | 37 | A program will gracefully exit when all the processing is done. 38 | 39 | Many times with Node we start servers, like this HTTP server: 40 | 41 | ```js 42 | const express = require('express') 43 | const app = express() 44 | 45 | app.get('/', (req, res) => { 46 | res.send('Hi!') 47 | }) 48 | 49 | app.listen(3000, () => console.log('Server ready')) 50 | ``` 51 | 52 | This program is never going to end. If you call `process.exit()`, any currently pending or running request is going to be aborted. This is _not nice_. 53 | 54 | In this case you need to send the command a SIGTERM signal, and handle that with the process signal handler: 55 | 56 | > Note: `process` does not require a "require", it's automatically available. 57 | 58 | ```js 59 | const express = require('express') 60 | 61 | const app = express() 62 | 63 | app.get('/', (req, res) => { 64 | res.send('Hi!') 65 | }) 66 | 67 | const server = app.listen(3000, () => console.log('Server ready')) 68 | 69 | process.on('SIGTERM', () => { 70 | server.close(() => { 71 | console.log('Process terminated') 72 | }) 73 | }) 74 | ``` 75 | 76 | > What are signals? Signals are a POSIX intercommunication system: a notification sent to a process in order to notify it of an event that occurred. 77 | 78 | `SIGKILL` is the signals that tells a process to immediately terminate, and would ideally act like `process.exit()`. 79 | 80 | `SIGTERM` is the signals that tells a process to gracefully terminate. It is the signal that's sent from process managers like `upstart` or `supervisord` and many others. 81 | 82 | You can send this signal from inside the program, in another function: 83 | 84 | ```js 85 | process.kill(process.pid, 'SIGTERM') 86 | ``` 87 | 88 | Or from another Node.js running program, or any other app running in your system that knows the PID of the process you want to terminate. 89 | -------------------------------------------------------------------------------- /documentation/0009-node-environment-variables/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to read environment variables from Node.js 3 | description: 'Learn how to read and make use of environment variables in a Node.js program' 4 | author: flaviocopes 5 | --- 6 | 7 | The `process` core module of Node provides the `env` property which hosts all the environment variables that were set at the moment the process was started. 8 | 9 | Here is an example that accesses the NODE_ENV environment variable, which is set to `development` by default. 10 | 11 | > Note: `process` does not require a "require", it's automatically available. 12 | 13 | ```js 14 | process.env.NODE_ENV // "development" 15 | ``` 16 | 17 | Setting it to "production" before the script runs will tell Node that this is a production environment. 18 | 19 | In the same way you can access any custom environment variable you set. 20 | -------------------------------------------------------------------------------- /documentation/0010-node-hosting/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Where to host a Node.js app 3 | description: 'A Node.js application can be hosted in a lot of places, depending on your needs. This is a list of all the various options you have at your disposal' 4 | author: flaviocopes 5 | --- 6 | 7 | Here is a non-exhaustive list of the options you can explore when you want to deploy your app and make it publicly accessible. 8 | 9 | I will list the options from simplest and constrained to more complex and powerful. 10 | 11 | 12 | 13 | - [Simplest option ever: local tunnel](#simplest-option-ever-local-tunnel) 14 | - [Zero configuration deployments](#zero-configuration-deployments) 15 | - [Glitch](#glitch) 16 | - [Codepen](#codepen) 17 | - [Serverless](#serverless) 18 | - [PAAS](#paas) 19 | - [Zeit Now](#zeit-now) 20 | - [Nanobox](#nanobox) 21 | - [Heroku](#heroku) 22 | - [Microsoft Azure](#microsoft-azure) 23 | - [Google Cloud Platform](#google-cloud-platform) 24 | - [Virtual Private Server](#virtual-private-server) 25 | - [Bare metal](#bare-metal) 26 | 27 | 28 | 29 | ## Simplest option ever: local tunnel 30 | 31 | Even if you have a dynamic IP, or you're under a NAT, you can deploy your app and serve the requests right from your computer using a local tunnel. 32 | 33 | This option is suited for some quick testing, demo a product or sharing of an app with a very small group of people. 34 | 35 | A very nice tool for this, available on all platforms, is [**ngrok**](https://ngrok.com/). 36 | 37 | Using it, you can just type `ngrok PORT` and the PORT you want is exposed to the internet. You will get a ngrok.io domain, but with a paid subscription you can get a custom URL as well as more security options (remember that you are opening your machine to the public Internet). 38 | 39 | Another service you can use is 40 | 41 | ## Zero configuration deployments 42 | 43 | ### Glitch 44 | 45 | [Glitch](https://glitch.com) is a playground and a way to build your apps faster than ever, and see them live on their own glitch.com subdomain. You cannot currently have a a custom domain, and there are a few [restrictions](https://glitch.com/faq#restrictions) in place, but it's really great to prototype. It looks fun (and this is a plus), and it's not a dumbed down environment - you get all the power of Node.js, a CDN, secure storage for credentials, GitHub import/export and much more. 46 | 47 | Provided by the company behind FogBugz and Trello (and co-creators of Stack Overflow). 48 | 49 | I use it a lot for demo purposes. 50 | 51 | ### Codepen 52 | 53 | [Codepen](https://codepen.io) is an amazing platform and community. You can create a project with multiple files, and deploy it with a custom domain. 54 | 55 | ## Serverless 56 | 57 | A way to publish your apps, and have no server at all to manage, is Serverless. Serverless is a paradigm where you publish your apps as **functions**, and they respond on a network endpoint (also called FAAS - Functions As A Service). 58 | 59 | To very popular solutions are 60 | 61 | - [Serverless Framework](https://serverless.com/framework/) 62 | - [Standard Library](https://stdlib.com/) 63 | 64 | They both provide an abstraction layer to publishing on AWS Lambda and other FAAS solutions based on Azure or the Google Cloud offering. 65 | 66 | ## PAAS 67 | 68 | PAAS stands for Platform As A Service. These platforms take away a lot of things you should otherwise worry about when deploying your application. 69 | 70 | ### Zeit Now 71 | 72 | Zeit is an interesting option. You just type `now` in your terminal, and it takes care of deploying your application. There is a free version with limitations, and the paid version is more powerful. You simply forget that there's a server, you just deploy the app. 73 | 74 | ### Nanobox 75 | 76 | [Nanobox](https://nanobox.io) 77 | 78 | ### Heroku 79 | 80 | Heroku is an amazing platform. 81 | 82 | This is a great article on [getting started with Node.js on Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs). 83 | 84 | ### Microsoft Azure 85 | 86 | Azure is the Microsoft Cloud offering. 87 | 88 | Check out how to [create a Node.js web app in Azure](https://docs.microsoft.com/en-us/microsoftteams/platform/get-started/get-started-nodejs). 89 | 90 | ### Google Cloud Platform 91 | 92 | Google Cloud is an amazing structure for your apps. 93 | 94 | They have a good [Node.js Documentation Section](https://cloud.google.com/node/) 95 | 96 | ## Virtual Private Server 97 | 98 | In this section you find the usual suspects, ordered from more user friendly to less user friendly: 99 | 100 | - [Digital Ocean](https://www.digitalocean.com) 101 | - [Linode](https://www.linode.com/) 102 | - [Amazon Web Services](https://aws.amazon.com) 103 | 104 | Since they provide an empty Linux machine on which you can work, there is no specific tutorial for these. 105 | 106 | There are lots more options in the VPS category, those are just some of the most popular. 107 | 108 | ## Bare metal 109 | 110 | Another solution is to get a bare metal server, install a Linux distribution, connect it to the internet (or rent one monthly, like you can do using the [Vultr Bare Metal](https://www.vultr.com/pricing/baremetal/) service) 111 | -------------------------------------------------------------------------------- /documentation/0011-node-repl/globals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0011-node-repl/globals.png -------------------------------------------------------------------------------- /documentation/0011-node-repl/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to use the Node.js REPL 3 | description: "REPL stands for Read-Evaluate-Print-Loop, and it's a great way to explore the Node features in a quick way" 4 | author: flaviocopes 5 | --- 6 | 7 | The `node` command is the one we use to run our Node.js scripts: 8 | 9 | ```sh 10 | node script.js 11 | ``` 12 | 13 | If we omit the filename, we use it in REPL mode: 14 | 15 | ```sh 16 | node 17 | ``` 18 | 19 | If you try it now in your terminal, this is what happens: 20 | 21 | ```txt 22 | ❯ node 23 | > 24 | ``` 25 | 26 | the command stays in idle mode and waits for us to enter something. 27 | 28 | > Tip: if you are unsure how to open your terminal, google "How to open terminal on ". 29 | 30 | The REPL is waiting for us to enter some JavaScript code, to be more precise. 31 | 32 | Start simple and enter 33 | 34 | ``` 35 | > console.log('test') 36 | test 37 | undefined 38 | > 39 | ``` 40 | 41 | The first value, `test`, is the output we told the console to print, then we get undefined which is the return value of running `console.log()`. 42 | 43 | We can now enter a new line of JavaScript. 44 | 45 | ## Use the tab to autocomplete 46 | 47 | The cool thing about the REPL is that it's interactive. 48 | 49 | As you write your code, if you press the `tab` key the REPL will try to autocomplete what you wrote to match a variable you already defined or a predefined one. 50 | 51 | ## Exploring JavaScript objects 52 | 53 | Try entering the name of a JavaScript class, like `Number`, add a dot and press `tab`. 54 | 55 | The REPL will print all the properties and methods you can access on that class: 56 | 57 | ![Pressing tab reveals object properties](tab.png) 58 | 59 | ## Explore global objects 60 | 61 | You can inspect the globals you have access to by typing `global.` and pressing `tab`: 62 | 63 | ![Globals](globals.png) 64 | 65 | ## The \_ special variable 66 | 67 | If after some code you type `_`, that is going to print the result of the last operation. 68 | 69 | ## Dot commands 70 | 71 | The REPL has some special commands, all starting with a dot `.`. They are 72 | 73 | - `.help`: shows the dot commands help 74 | - `.editor`: enables editor more, to write multiline JavaScript code with ease. Once you are in this mode, enter ctrl-D to run the code you wrote. 75 | - `.break`: when inputting a multi-line expression, entering the .break command will abort further input. Same as pressing ctrl-C. 76 | - `.clear`: resets the REPL context to an empty object and clears any multi-line expression currently being input. 77 | - `.load`: loads a JavaScript file, relative to the current working directory 78 | - `.save`: saves all you entered in the REPL session to a file (specify the filename) 79 | - `.exit`: exists the repl (same as pressing ctrl-C two times) 80 | 81 | The REPL knows when you are typing a multi-line statement without the need to invoke `.editor`. 82 | 83 | For example if you start typing an iteration like this: 84 | 85 | ```js 86 | [1, 2, 3].forEach(num => { 87 | ``` 88 | 89 | and you press `enter`, the REPL will go to a new line that starts with 3 dots, indicating you can now continue to work on that block. 90 | 91 | ```js 92 | ... console.log(num) 93 | ... }) 94 | ``` 95 | 96 | If you type `.break` at the end of a line, the multiline mode will stop and the statement will not be executed. 97 | -------------------------------------------------------------------------------- /documentation/0011-node-repl/tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0011-node-repl/tab.png -------------------------------------------------------------------------------- /documentation/0012-node-cli-args/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Node, accept arguments from the command line 3 | description: 'How to accept arguments in a Node.js program passed from the command line' 4 | author: flaviocopes 5 | --- 6 | 7 | You can pass any number of arguments when invoking a Node.js application using 8 | 9 | ```sh 10 | node app.js 11 | ``` 12 | 13 | Arguments can be standalone or have a key and a value. 14 | 15 | For example: 16 | 17 | ```sh 18 | node app.js joe 19 | ``` 20 | 21 | or 22 | 23 | ```sh 24 | node app.js name=joe 25 | ``` 26 | 27 | This changes how you will retrieve this value in the Node code. 28 | 29 | The way you retrieve it is using the `process` object built into Node. 30 | 31 | It exposes an `argv` property, which is an array that contains all the command line invocation arguments. 32 | 33 | The first argument is the full path of the `node` command. 34 | 35 | The second element is the full path of the file being executed. 36 | 37 | All the additional arguments are present from the third position going forward. 38 | 39 | You can iterate over all the arguments (including the node path and the file path) using a loop: 40 | 41 | ```js 42 | process.argv.forEach((val, index) => { 43 | console.log(`${index}: ${val}`) 44 | }) 45 | ``` 46 | 47 | You can get only the additional arguments by creating a new array that excludes the first 2 params: 48 | 49 | ```js 50 | const args = process.argv.slice(2) 51 | ``` 52 | 53 | If you have one argument without an index name, like this: 54 | 55 | ```sh 56 | node app.js joe 57 | ``` 58 | 59 | you can access it using 60 | 61 | ```js 62 | const args = process.argv.slice(2) 63 | args[0] 64 | ``` 65 | 66 | In this case: 67 | 68 | ```sh 69 | node app.js name=joe 70 | ``` 71 | 72 | `args[0]` is `name=joe`, and you need to 73 | parse it. The best way to do so is by using the [`minimist`](https://www.npmjs.com/package/minimist) library, which helps dealing with arguments: 74 | 75 | ```js 76 | const args = require('minimist')(process.argv.slice(2)) 77 | args['name'] //joe 78 | ``` 79 | 80 | This time you need to use double dashes before each argument name: 81 | 82 | ```sh 83 | node app.js --name=joe 84 | ``` 85 | -------------------------------------------------------------------------------- /documentation/0013-node-output-to-cli/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Output to the command line using Node 3 | description: 'How to print to the command line console using Node, from the basic console.log to more complex scenarios' 4 | author: flaviocopes 5 | --- 6 | 7 | 8 | 9 | - [Basic output using the console module](#basic-output-using-the-console-module) 10 | - [Clear the console](#clear-the-console) 11 | - [Counting elements](#counting-elements) 12 | - [Print the stack trace](#print-the-stack-trace) 13 | - [Calculate the time spent](#calculate-the-time-spent) 14 | - [stdout and stderr](#stdout-and-stderr) 15 | - [Color the output](#color-the-output) 16 | - [Create a progress bar](#create-a-progress-bar) 17 | 18 | 19 | 20 | ## Basic output using the console module 21 | 22 | Node provides a [`console` module](https://nodejs.org/api/console.html) which provides tons of very useful ways to interact with the command line. 23 | 24 | It is basically the same as the `console` object you find in the browser. 25 | 26 | The most basic and most used method is `console.log()`, which prints the string you pass to it to the console. 27 | 28 | If you pass an object, it will render it as a string. 29 | 30 | You can pass multiple variables to `console.log`, for example: 31 | 32 | ```js 33 | const x = 'x' 34 | const y = 'y' 35 | console.log(x, y) 36 | ``` 37 | 38 | and Node will print both. 39 | 40 | We can also format pretty phrases by passing variables and a format specifier. 41 | 42 | For example: 43 | 44 | ```js 45 | console.log('My %s has %d years', 'cat', 2) 46 | ``` 47 | 48 | - `%s` format a variable as a string 49 | - `%d` or `%i` format a variable as an integer 50 | - `%f` format a variable as a floating point number 51 | - `%O` used to print an object representation 52 | 53 | Example: 54 | 55 | ```js 56 | console.log('%O', Number) 57 | ``` 58 | 59 | ## Clear the console 60 | 61 | `console.clear()` clears the console (the behavior might depend on the console used) 62 | 63 | ## Counting elements 64 | 65 | `console.count()` is a handy method. 66 | 67 | Take this code: 68 | 69 | ```js 70 | const x = 1 71 | const y = 2 72 | const z = 3 73 | console.count( 74 | 'The value of x is ' + x + ' and has been checked .. how many times?' 75 | ) 76 | console.count( 77 | 'The value of x is ' + x + ' and has been checked .. how many times?' 78 | ) 79 | console.count( 80 | 'The value of y is ' + y + ' and has been checked .. how many times?' 81 | ) 82 | ``` 83 | 84 | What happens is that count will count the number of times a string is printed, and print the count next to it: 85 | 86 | You can just count apples and oranges: 87 | 88 | ```js 89 | const oranges = ['orange', 'orange'] 90 | const apples = ['just one apple'] 91 | oranges.forEach(fruit => { 92 | console.count(fruit) 93 | }) 94 | apples.forEach(fruit => { 95 | console.count(fruit) 96 | }) 97 | ``` 98 | 99 | ## Print the stack trace 100 | 101 | There might be cases where it's useful to print the call stack trace of a function, maybe to answer the question _how did you reach that part of the code?_ 102 | 103 | You can do so using `console.trace()`: 104 | 105 | ```js 106 | const function2 = () => console.trace() 107 | const function1 = () => function2() 108 | function1() 109 | ``` 110 | 111 | This will print the stack trace. This is what's printed if we try this in the Node REPL: 112 | 113 | ```txt 114 | Trace 115 | at function2 (repl:1:33) 116 | at function1 (repl:1:25) 117 | at repl:1:1 118 | at ContextifyScript.Script.runInThisContext (vm.js:44:33) 119 | at REPLServer.defaultEval (repl.js:239:29) 120 | at bound (domain.js:301:14) 121 | at REPLServer.runBound [as eval] (domain.js:314:12) 122 | at REPLServer.onLine (repl.js:440:10) 123 | at emitOne (events.js:120:20) 124 | at REPLServer.emit (events.js:210:7) 125 | ``` 126 | 127 | ## Calculate the time spent 128 | 129 | You can easily calculate how much time a function takes to run, using `time()` and `timeEnd()` 130 | 131 | ```js 132 | const doSomething = () => console.log('test') 133 | const measureDoingSomething = () => { 134 | console.time('doSomething()') 135 | //do something, and measure the time it takes 136 | doSomething() 137 | console.timeEnd('doSomething()') 138 | } 139 | measureDoingSomething() 140 | ``` 141 | 142 | ## stdout and stderr 143 | 144 | As we saw console.log is great for printing messages in the Console. This is what's called the standard output, or `stdout`. 145 | 146 | `console.error` prints to the `stderr` stream. 147 | 148 | It will not appear in the console, but it will appear in the error log. 149 | 150 | ## Color the output 151 | 152 | You can color the output of your text in the console by using [escape sequences](https://gist.github.com/chrisopedia/8754917). An escape sequence is a set of characters that identifies a color. 153 | 154 | Example: 155 | 156 | ```js 157 | console.log('\x1b[33m%s\x1b[0m', 'hi!') 158 | ``` 159 | 160 | You can try that in the Node REPL, and it will print `hi!` in yellow. 161 | 162 | However, this is the low-level way to do this. The simplest way to go about coloring the console output is by using a library. [Chalk](https://github.com/chalk/chalk) is such a library, and in addition to coloring it also helps with other styling facilities, like making text bold, italic or underlined. 163 | 164 | You install it with `npm install chalk`, then you can use it: 165 | 166 | ```js 167 | const chalk = require('chalk') 168 | console.log(chalk.yellow('hi!')) 169 | ``` 170 | 171 | Using `chalk.yellow` is much more convenient than trying to remember the escape codes, and the code is much more readable. 172 | 173 | Check the project link posted above for more usage examples. 174 | 175 | ## Create a progress bar 176 | 177 | [Progress](https://www.npmjs.com/package/progress) is an awesome package to create a progress bar in the console. Install it using `npm install progress` 178 | 179 | This snippet creates a 10-step progress bar, and every 100ms one step is completed. When the bar completes we clear the interval: 180 | 181 | ```js 182 | const ProgressBar = require('progress') 183 | 184 | const bar = new ProgressBar(':bar', { total: 10 }) 185 | const timer = setInterval(() => { 186 | bar.tick() 187 | if (bar.complete) { 188 | clearInterval(timer) 189 | } 190 | }, 100) 191 | ``` 192 | -------------------------------------------------------------------------------- /documentation/0014-node-input-from-cli/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Accept input from the command line in Node 3 | description: 'How to make a Node.js CLI program interactive using the built-in readline Node module' 4 | author: flaviocopes 5 | --- 6 | 7 | How to make a Node.js CLI program interactive? 8 | 9 | Node since version 7 provides the [`readline` module](https://nodejs.org/api/readline.html) to perform exactly this: get input from a readable stream such as the `process.stdin` stream, which during the execution of a Node program is the terminal input, one line at a time. 10 | 11 | ```js 12 | const readline = require('readline').createInterface({ 13 | input: process.stdin, 14 | output: process.stdout 15 | }) 16 | 17 | readline.question(`What's your name?`, name => { 18 | console.log(`Hi ${name}!`) 19 | readline.close() 20 | }) 21 | ``` 22 | 23 | This piece of code asks the username, and once the text is entered and the user presses enter, we send a greeting. 24 | 25 | The `question()` method shows the first parameter (a question) and waits for the user input. It calls the callback function once enter is pressed. 26 | 27 | In this callback function, we close the readline interface. 28 | 29 | `readline` offers several other methods, and I'll let you check them out on the package documentation linked above. 30 | 31 | If you need to require a password, it's best to now echo it back, but instead showing a `*` symbol. 32 | 33 | The simplest way is to use the [`readline-sync` package](https://www.npmjs.com/package/readline-sync) which is very similar in terms of the API and handles this out of the box. 34 | 35 | A more complete and abstract solution is provided by the [Inquirer.js package](https://github.com/SBoudrias/Inquirer.js). 36 | 37 | You can install it using `npm install inquirer`, and then you can replicate the above code like this: 38 | 39 | ```js 40 | const inquirer = require('inquirer') 41 | 42 | var questions = [ 43 | { 44 | type: 'input', 45 | name: 'name', 46 | message: "What's your name?" 47 | } 48 | ] 49 | 50 | inquirer.prompt(questions).then(answers => { 51 | console.log(`Hi ${answers['name']}!`) 52 | }) 53 | ``` 54 | 55 | Inquirer.js lets you do many things like asking multiple choices, having radio buttons, confirmations, and more. 56 | 57 | It's worth knowing all the alternatives, especially the built-in ones provided by Node, but if you plan to take CLI input to the next level, Inquirer.js is an optimal choice. 58 | -------------------------------------------------------------------------------- /documentation/0015-node-export-module/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Expose functionality from a Node file using exports 3 | description: 'How to use the module.exports API to expose data to other files in your application, or to other applications as well' 4 | author: flaviocopes 5 | --- 6 | 7 | Node has a built-in module system. 8 | 9 | A Node.js file can import functionality exposed by other Node.js files. 10 | 11 | When you want to import something you use 12 | 13 | ```js 14 | const library = require('./library') 15 | ``` 16 | 17 | to import the functionality exposed in the `library.js` file that resides in the current file folder. 18 | 19 | In this file, functionality must be exposed before it can be imported by other files. 20 | 21 | Any other object or variable defined in the file by default is private and not exposed to the outer world. 22 | 23 | This is what the `module.exports` API offered by the [`module` system](https://nodejs.org/api/modules.html) allows us to do. 24 | 25 | When you assign an object or a function as a new `exports` property, that is the thing that's being exposed, and as such, it can be imported in other parts of your app, or in other apps as well. 26 | 27 | You can do so in 2 ways. 28 | 29 | The first is to assign an object to `module.exports`, which is an object provided out of the box by the module system, and this will make your file export _just that object_: 30 | 31 | ```js 32 | const car = { 33 | brand: 'Ford', 34 | model: 'Fiesta' 35 | } 36 | 37 | module.exports = car 38 | 39 | //..in the other file 40 | 41 | const car = require('./car') 42 | ``` 43 | 44 | The second way is to add the exported object as a property of `exports`. This way allows you to export multiple objects, functions or data: 45 | 46 | ```js 47 | const car = { 48 | brand: 'Ford', 49 | model: 'Fiesta' 50 | } 51 | 52 | exports.car = car 53 | ``` 54 | 55 | or directly 56 | 57 | ```js 58 | exports.car = { 59 | brand: 'Ford', 60 | model: 'Fiesta' 61 | } 62 | ``` 63 | 64 | And in the other file, you'll use it by referencing a property of your import: 65 | 66 | ```js 67 | const items = require('./items') 68 | items.car 69 | ``` 70 | 71 | or 72 | 73 | ```js 74 | const car = require('./items').car 75 | ``` 76 | 77 | What's the difference between `module.exports` and `exports`? 78 | 79 | The first exposes the object it points to. 80 | The latter exposes _the properties_ of the object it points to. 81 | -------------------------------------------------------------------------------- /documentation/0016-npm/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: An introduction to the npm package manager 3 | description: 'A quick guide to npm, the powerful package manager key to the success of Node.js. In January 2017 over 350000 packages were reported being listed in the npm registry, making it the biggest single language code repository on Earth, and you can be sure there is a package for (almost!) everything.' 4 | author: flaviocopes 5 | --- 6 | 7 | 8 | 9 | - [Introduction to npm](#introduction-to-npm) 10 | - [Downloads](#downloads) 11 | - [Installing all dependencies](#installing-all-dependencies) 12 | - [Installing a single package](#installing-a-single-package) 13 | - [Updating packages](#updating-packages) 14 | - [Versioning](#versioning) 15 | - [Running Tasks](#running-tasks) 16 | 17 | 18 | 19 | ## Introduction to npm 20 | 21 | `npm` is the standard package manager for Node.js. 22 | 23 | In January 2017 over 350000 packages were reported being listed in the npm registry, making it the biggest single language code repository on Earth, and you can be sure there is a package for (almost!) everything. 24 | 25 | It started as a way to download and manage dependencies of Node.js packages, but it has since become a tool used also in frontend JavaScript. 26 | 27 | There are many things that `npm` does. 28 | 29 | > Yarn is an alternative to npm. Make sure you check it out as well. 30 | 31 | ## Downloads 32 | 33 | `npm` manages downloads of dependencies of your project. 34 | 35 | ### Installing all dependencies 36 | 37 | If a project has a `packages.json` file, by running 38 | 39 | ```bash 40 | npm install 41 | ``` 42 | 43 | it will install everything the project needs, in the `node_modules` folder, creating it if it's not existing already. 44 | 45 | ### Installing a single package 46 | 47 | You can also install a specific package by running 48 | 49 | ```bash 50 | npm install 51 | ``` 52 | 53 | Often you'll see more flags added to this command: 54 | 55 | - `--save` installs and adds the entry to the `package.json` file _dependencies_ 56 | - `--save-dev` installs and adds the entry to the `package.json` file _devDependencies_ 57 | 58 | The difference is mainly that devDependencies are usually development tools, like a testing library, while `dependencies` are bundled with the app in production. 59 | 60 | ### Updating packages 61 | 62 | Updating is also made easy, by running 63 | 64 | ``` 65 | npm update 66 | ``` 67 | 68 | `npm` will check all packages for a newer version that satisfies your versioning constraints. 69 | 70 | You can specify a single package to update as well: 71 | 72 | ``` 73 | npm update 74 | ``` 75 | 76 | ## Versioning 77 | 78 | In addition to plain downloads, `npm` also manages **versioning**, so you can specify any specific version of a package, or require a version higher or lower than what you need. 79 | 80 | Many times you'll find that a library is only compatible with a major release of another library. 81 | 82 | Or a bug in the latest release of a lib, still unfixed, is causing an issue. 83 | 84 | Specifying an explicit version of a library also helps to keep everyone on the same exact version of a package, so that the whole team runs the same version until the `package.json` file is updated. 85 | 86 | In all those cases, versioning helps a lot, and `npm` follows the semantic versioning (semver) standard. 87 | 88 | ## Running Tasks 89 | 90 | The package.json file supports a format for specifying command line tasks that can be run by using 91 | 92 | ``` 93 | npm run 94 | ``` 95 | 96 | For example: 97 | 98 | ```js 99 | { 100 | "scripts": { 101 | "start-dev": "node lib/server-development", 102 | "start": "node lib/server-production" 103 | }, 104 | } 105 | ``` 106 | 107 | It's very common to use this feature to run Webpack: 108 | 109 | ```js 110 | { 111 | "scripts": { 112 | "watch": "webpack --watch --progress --colors --config webpack.conf.js", 113 | "dev": "webpack --progress --colors --config webpack.conf.js", 114 | "prod": "NODE_ENV=production webpack -p --config webpack.conf.js", 115 | }, 116 | } 117 | ``` 118 | 119 | So instead of typing those long commands, which are easy to forget or mistype, you can run 120 | 121 | ``` 122 | $ npm run watch 123 | $ npm run dev 124 | $ npm run prod 125 | ``` 126 | -------------------------------------------------------------------------------- /documentation/0017-where-npm-install-packages/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Where does npm install the packages? 3 | description: 'How to find out where npm installs the packages' 4 | author: flaviocopes 5 | --- 6 | 7 | When you install a package using `npm` you can perform 2 types of installation: 8 | 9 | - a local install 10 | - a global install 11 | 12 | By default, when you type an `npm install` command, like: 13 | 14 | ```bash 15 | npm install lodash 16 | ``` 17 | 18 | the package is installed in the current file tree, under the `node_modules` subfolder. 19 | 20 | As this happens, `npm` also adds the `lodash` entry in the `dependencies` property of the `package.json` file present in the current folder. 21 | 22 | A global installation is performed using the `-g` flag: 23 | 24 | ```bash 25 | npm install -g lodash 26 | ``` 27 | 28 | When this happens, npm won't install the package under the local folder, but instead, it will use a global location. 29 | 30 | Where, exactly? 31 | 32 | The `npm root -g` command will tell you where that exact location is on your machine. 33 | 34 | On macOS or Linux this location could be `/usr/local/lib/node_modules`. 35 | On Windows it could be `C:\Users\YOU\AppData\Roaming\npm\node_modules` 36 | 37 | If you use `nvm` to manage Node.js versions, however, that location would differ. 38 | 39 | I for example use `nvm` and my packages location was shown as `/Users/joe/.nvm/versions/node/v8.9.0/lib/node_modules`. 40 | -------------------------------------------------------------------------------- /documentation/0018-how-to-use-npm-package/binary-files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0018-how-to-use-npm-package/binary-files.png -------------------------------------------------------------------------------- /documentation/0018-how-to-use-npm-package/cow-say.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0018-how-to-use-npm-package/cow-say.png -------------------------------------------------------------------------------- /documentation/0018-how-to-use-npm-package/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to use or execute a package installed using npm 3 | description: 'How to include and use in your code a package installed in your node_modules folder' 4 | author: flaviocopes 5 | --- 6 | 7 | When you install using `npm` a package into your `node_modules` folder, or also globally, how do you use it in your Node code? 8 | 9 | Say you install `lodash`, the popular JavaScript utility library, using 10 | 11 | ```bash 12 | npm install lodash 13 | ``` 14 | 15 | This is going to install the package in the local `node_modules` folder. 16 | 17 | To use it in your code, you just need to import it into your program using `require`: 18 | 19 | ```js 20 | const _ = require('lodash') 21 | ``` 22 | 23 | What if your package is an executable? 24 | 25 | In this case, it will put the executable file under the `node_modules/.bin/` folder. 26 | 27 | One easy way to demonstrate this is [cowsay](https://www.npmjs.com/package/cowsay). 28 | 29 | The cowsay package provides a command line program that can be executed to make a cow say something (and other animals as well 🦊). 30 | 31 | When you install the package using `npm install cowsay`, it will install itself and a few dependencies in the node_modules folder: 32 | 33 | ![The node_modules folder content](node_modules-content.png) 34 | 35 | There is a hidden .bin folder, which contains symbolic links to the cowsay binaries: 36 | 37 | ![The binary files](binary-files.png) 38 | 39 | How do you execute those? 40 | 41 | You can of course type `./node_modules/.bin/cowsay` to run it, and it works, but npx, included in the recent versions of npm (since 5.2), is a much better option. You just run: 42 | 43 | ```sh 44 | npx cowsay 45 | ``` 46 | 47 | and npx will find the package location. 48 | 49 | ![Cow says something](cow-say.png) 50 | -------------------------------------------------------------------------------- /documentation/0018-how-to-use-npm-package/node_modules-content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0018-how-to-use-npm-package/node_modules-content.png -------------------------------------------------------------------------------- /documentation/0020-package-lock-json/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The package-lock.json file 3 | description: "The package-lock.json file is automatically generated when installing node packages. Learn what it's about" 4 | author: flaviocopes 5 | --- 6 | 7 | In version 5, npm introduced the `package-lock.json` file. 8 | 9 | What's that? You probably know about the `package.json` file, which is much more common and has been around for much longer. 10 | 11 | The goal of the file is to keep track of the exact version of every package that is installed so that a product is 100% reproducible in the same way even if packages are updated by their maintainers. 12 | 13 | This solves a very specific problem that `package.json` left unsolved. In package.json you can set which versions you want to upgrade to (patch or minor), using the **semver** notation, for example: 14 | 15 | - if you write `~0.13.0`, you want to only update patch releases: `0.13.1` is ok, but `0.14.0` is not. 16 | - if you write `^0.13.0`, you want to update patch and minor releases: `0.13.1`, `0.14.0` and so on. 17 | - if you write `0.13.0`, that is the exact version that will be used, always 18 | 19 | You don't commit to Git your node_modules folder, which is generally huge, and when you try to replicate the project on another machine by using the `npm install` command, if you specified the `~` syntax and a patch release of a package has been released, that one is going to be installed. Same for `^` and minor releases. 20 | 21 | > If you specify exact versions, like `0.13.0` in the example, you are not affected by this problem. 22 | 23 | It could be you, or another person trying to initialize the project on the other side of the world by running `npm install`. 24 | 25 | So your original project and the newly initialized project are actually different. Even if a patch or minor release should not introduce breaking changes, we all know bugs can (and so, they will) slide in. 26 | 27 | The `package-lock.json` sets your currently installed version of each package **in stone**, and `npm` will use those exact versions when running `npm install`. 28 | 29 | This concept is not new, and other programming languages package managers (like Composer in PHP) use a similar system for years. 30 | 31 | The `package-lock.json` file needs to be committed to your Git repository, so it can be fetched by other people, if the project is public or you have collaborators, or if you use Git as a source for deployments. 32 | 33 | The dependencies versions will be updated in the `package-lock.json` file when you run `npm update`. 34 | 35 | ## An example 36 | 37 | This is an example structure of a `package-lock.json` file we get when we run `npm install cowsay` in an empty folder: 38 | 39 | ```json 40 | { 41 | "requires": true, 42 | "lockfileVersion": 1, 43 | "dependencies": { 44 | "ansi-regex": { 45 | "version": "3.0.0", 46 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3. 47 | 0.0.tgz", 48 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 49 | }, 50 | "cowsay": { 51 | "version": "1.3.1", 52 | "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz" 53 | , 54 | "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkM 55 | Ajufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==", 56 | "requires": { 57 | "get-stdin": "^5.0.1", 58 | "optimist": "~0.6.1", 59 | "string-width": "~2.1.1", 60 | "strip-eof": "^1.0.0" 61 | } 62 | }, 63 | "get-stdin": { 64 | "version": "5.0.1", 65 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0. 66 | 1.tgz", 67 | "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=" 68 | }, 69 | "is-fullwidth-code-point": { 70 | "version": "2.0.0", 71 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/ 72 | is-fullwidth-code-point-2.0.0.tgz", 73 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 74 | }, 75 | "minimist": { 76 | "version": "0.0.10", 77 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10 78 | .tgz", 79 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" 80 | }, 81 | "optimist": { 82 | "version": "0.6.1", 83 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 84 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 85 | 86 | "requires": { 87 | "minimist": "~0.0.1", 88 | "wordwrap": "~0.0.2" 89 | } 90 | }, 91 | "string-width": { 92 | "version": "2.1.1", 93 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 94 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 95 | "requires": { 96 | "is-fullwidth-code-point": "^2.0.0", 97 | "strip-ansi": "^4.0.0" 98 | } 99 | }, 100 | "strip-ansi": { 101 | "version": "4.0.0", 102 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 103 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 104 | "requires": { 105 | "ansi-regex": "^3.0.0" 106 | } 107 | }, 108 | "strip-eof": { 109 | "version": "1.0.0", 110 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 111 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" 112 | }, 113 | "wordwrap": { 114 | "version": "0.0.3", 115 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 116 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" 117 | } 118 | } 119 | } 120 | ``` 121 | 122 | We installed `cowsay`, which depends on 123 | 124 | - `get-stdin` 125 | - `optimist` 126 | - `string-width` 127 | - `strip-eof` 128 | 129 | In turn, those packages require other packages, as we can see from the `requires` property that some have: 130 | 131 | - `ansi-regex` 132 | - `is-fullwidth-code-point` 133 | - `minimist` 134 | - `wordwrap` 135 | - `strip-eof` 136 | 137 | They are added in alphabetical order into the file, and each one has a `version` field, a `resolved` field that points to the package location, and an `integrity` string that we can use to verify the package. 138 | -------------------------------------------------------------------------------- /documentation/0021-npm-know-version-installed/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Find the installed version of an npm package 3 | description: 'How to find out which version of a particular package you have installed in your app' 4 | author: flaviocopes 5 | --- 6 | 7 | To see the latest version of all the npm package installed, including their dependencies: 8 | 9 | ```sh 10 | npm list 11 | ``` 12 | 13 | Example: 14 | 15 | ```txt 16 | ❯ npm list 17 | /Users/joe/dev/node/cowsay 18 | └─┬ cowsay@1.3.1 19 | ├── get-stdin@5.0.1 20 | ├─┬ optimist@0.6.1 21 | │ ├── minimist@0.0.10 22 | │ └── wordwrap@0.0.3 23 | ├─┬ string-width@2.1.1 24 | │ ├── is-fullwidth-code-point@2.0.0 25 | │ └─┬ strip-ansi@4.0.0 26 | │ └── ansi-regex@3.0.0 27 | └── strip-eof@1.0.0 28 | ``` 29 | 30 | You can also just open the `package-lock.json` file, but this involves some visual scanning. 31 | 32 | `npm list -g` is the same, but for globally installed packages. 33 | 34 | To get only your top-level packages (basically, the ones you told npm to install and you listed in the `package.json`), run `npm list --depth=0`: 35 | 36 | ```txt 37 | ❯ npm list --depth=0 38 | /Users/joe/dev/node/cowsay 39 | └── cowsay@1.3.1 40 | ``` 41 | 42 | You can get the version of a specific package by specifying the name: 43 | 44 | ```txt 45 | ❯ npm list cowsay 46 | /Users/joe/dev/node/cowsay 47 | └── cowsay@1.3.1 48 | ``` 49 | 50 | This also works for dependencies of packages you installed: 51 | 52 | ```txt 53 | ❯ npm list minimist 54 | /Users/joe/dev/node/cowsay 55 | └─┬ cowsay@1.3.1 56 | └─┬ optimist@0.6.1 57 | └── minimist@0.0.10 58 | ``` 59 | 60 | If you want to see what's the latest available version of the package on the npm repository, run `npm view [package_name] version`: 61 | 62 | ```txt 63 | ❯ npm view cowsay version 64 | 65 | 1.3.1 66 | ``` 67 | -------------------------------------------------------------------------------- /documentation/0022-npm-install-previous-package-version/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Install an older version of an npm package 3 | description: 'Learn how to install an older version of an npm package, something that might be useful to solve a compatibility problem' 4 | author: flaviocopes 5 | --- 6 | 7 | You can install an old version of an npm package using the `@` syntax: 8 | 9 | ```sh 10 | npm install @ 11 | ``` 12 | 13 | Example: 14 | 15 | ```sh 16 | npm install cowsay 17 | ``` 18 | 19 | installs version 1.3.1 (at the time of writing). 20 | 21 | Install version 1.2.0 with: 22 | 23 | ```sh 24 | npm install cowsay@1.2.0 25 | ``` 26 | 27 | The same can be done with global packages: 28 | 29 | ```sh 30 | npm install -g webpack@4.16.4 31 | ``` 32 | 33 | You might also be interested in listing all the previous version of a package. You can do it with `npm view versions`: 34 | 35 | ```txt 36 | ❯ npm view cowsay versions 37 | 38 | [ '1.0.0', 39 | '1.0.1', 40 | '1.0.2', 41 | '1.0.3', 42 | '1.1.0', 43 | '1.1.1', 44 | '1.1.2', 45 | '1.1.3', 46 | '1.1.4', 47 | '1.1.5', 48 | '1.1.6', 49 | '1.1.7', 50 | '1.1.8', 51 | '1.1.9', 52 | '1.2.0', 53 | '1.2.1', 54 | '1.3.0', 55 | '1.3.1' ] 56 | ``` 57 | -------------------------------------------------------------------------------- /documentation/0023-update-npm-dependencies/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Update all the Node dependencies to their latest version 3 | description: 'How do you update all the npm dependencies store in the package.json file, to their latest version available?' 4 | author: flaviocopes 5 | --- 6 | 7 | When you install a package using `npm install `, the latest available version of the package is downloaded and put in the `node_modules` folder, and a corresponding entry is added to the `package.json` and `package-lock.json` files that are present in your current folder. 8 | 9 | npm calculates the dependencies and installs the latest available version of those as well. 10 | 11 | Let's say you install [`cowsay`](https://www.npmjs.com/package/cowsay), a cool command line tool that lets you make a cow say _things_. 12 | 13 | When you `npm install cowsay`, this entry is added to the `package.json` file: 14 | 15 | ```json 16 | { 17 | "dependencies": { 18 | "cowsay": "^1.3.1" 19 | } 20 | } 21 | ``` 22 | 23 | and this is an extract of `package-lock.json`, where we removed the nested dependencies for clarity: 24 | 25 | ```json 26 | { 27 | "requires": true, 28 | "lockfileVersion": 1, 29 | "dependencies": { 30 | "cowsay": { 31 | "version": "1.3.1", 32 | "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz", 33 | "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkMAjufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==", 34 | "requires": { 35 | "get-stdin": "^5.0.1", 36 | "optimist": "~0.6.1", 37 | "string-width": "~2.1.1", 38 | "strip-eof": "^1.0.0" 39 | } 40 | } 41 | } 42 | } 43 | ``` 44 | 45 | Now those 2 files tell us that we installed version `1.3.1` of cowsay, and our rule for updates is `^1.3.1`, which for the npm versioning rules means that npm can update to patch and minor releases: `0.13.1`, `0.14.0` and so on. 46 | 47 | If there is a new minor or patch release and we type `npm update`, the installed version is updated, and the `package-lock.json` file diligently filled with the new version. 48 | 49 | `package.json` remains unchanged. 50 | 51 | To discover new releases of the packages, you run `npm outdated`. 52 | 53 | Here's the list of a few outdated packages in one repository that wasn't updated for quite a while: 54 | 55 | ![](outdated-packages.png) 56 | 57 | Some of those updates are major releases. Running `npm update` won't update the version of those. Major releases are never updated in this way because they (by definition) introduce breaking changes, and `npm` want to save you trouble. 58 | 59 | To update to a new major version all the packages, install the `npm-check-updates` package globally: 60 | 61 | ```sh 62 | npm install -g npm-check-updates 63 | ``` 64 | 65 | then run it: 66 | 67 | ```sh 68 | ncu -u 69 | ``` 70 | 71 | this will upgrade all the version hints in the `package.json` file, to `dependencies` and `devDependencies`, so npm can install the new major version. 72 | 73 | You are now ready to run the update: 74 | 75 | ```sh 76 | npm update 77 | ``` 78 | 79 | If you just downloaded the project without the `node_modules` dependencies and you want to install the shiny new versions first, just run 80 | 81 | ```sh 82 | npm install 83 | ``` 84 | -------------------------------------------------------------------------------- /documentation/0023-update-npm-dependencies/outdated-packages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0023-update-npm-dependencies/outdated-packages.png -------------------------------------------------------------------------------- /documentation/0023-update-npm-dependencies/updated-packages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0023-update-npm-dependencies/updated-packages.png -------------------------------------------------------------------------------- /documentation/0024-npm-semantic-versioning/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Semantic Versioning using npm 3 | description: 'Semantic Versioning is a convention used to provide a meaning to versions' 4 | author: flaviocopes 5 | --- 6 | 7 | If there's one great thing in Node.js packages, is that all agreed on using Semantic Versioning for their version numbering. 8 | 9 | The Semantic Versioning concept is simple: all versions have 3 digits: `x.y.z`. 10 | 11 | - the first digit is the major version 12 | - the second digit is the minor version 13 | - the third digit is the patch version 14 | 15 | When you make a new release, you don't just up a number as you please, but you have rules: 16 | 17 | - you up the major version when you make incompatible API changes 18 | - you up the minor version when you add functionality in a backward-compatible manner 19 | - you up the patch version when you make backward-compatible bug fixes 20 | 21 | The convention is adopted all across programming languages, and it is very important that every `npm` package adheres to it, because the whole system depends on that. 22 | 23 | Why is that so important? 24 | 25 | Because `npm` set some rules we can use in the `package.json` file to choose which versions it can update our packages to, when we run `npm update`. 26 | 27 | The rules use those symbols: 28 | 29 | - `^` 30 | - `~` 31 | - `>` 32 | - `>=` 33 | - `<` 34 | - `<=` 35 | - `=` 36 | - `-` 37 | - `||` 38 | 39 | Let's see those rules in detail: 40 | 41 | - `^`: if you write `^0.13.0` when running `npm update` it can update to patch and minor releases: `0.13.1`, `0.14.0` and so on. 42 | - `~`: if you write `~0.13.0`, when running `npm update` it can update to patch releases: `0.13.1` is ok, but `0.14.0` is not. 43 | - `>`: you accept any version higher than the one you specify 44 | - `>=`: you accept any version equal to or higher than the one you specify 45 | - `<=`: you accept any version equal or lower to the one you specify 46 | - `<`: you accept any version lower to the one you specify 47 | - `=`: you accept that exact version 48 | - `-`: you accept a range of versions. Example: `2.1.0 - 2.6.2` 49 | - `||`: you combine sets. Example: `< 2.1 || > 2.6` 50 | 51 | You can combine some of those notations, for example use `1.0.0 || >=1.1.0 <1.2.0` to either use 1.0.0 or one release from 1.1.0 up, but lower than 1.2.0. 52 | 53 | There are other rules, too: 54 | 55 | - no symbol: you accept only that specific version you specify (`1.2.1`) 56 | - `latest`: you want to use the latest version available 57 | -------------------------------------------------------------------------------- /documentation/0025-npm-uninstall-packages/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Uninstalling npm packages 3 | description: 'How to uninstall an npm Node package, locally or globally' 4 | author: flaviocopes 5 | --- 6 | 7 | To uninstall a package you have previously installed **locally** (using `npm install ` in the `node_modules` folder, run 8 | 9 | ```sh 10 | npm uninstall 11 | ``` 12 | 13 | from the project root folder (the folder that contains the node_modules folder). 14 | 15 | Using the `-S` flag, or `--save`, this operation will also remove the reference in the `package.json` file. 16 | 17 | If the package was a development dependency, listed in the devDependencies of the `package.json` file, you must use the `-D` / `--save-dev` flag to remove it from the file: 18 | 19 | ```sh 20 | npm uninstall -S 21 | npm uninstall -D 22 | ``` 23 | 24 | If the package is installed **globally**, you need to add the `-g` / `--global` flag: 25 | 26 | ```sh 27 | npm uninstall -g 28 | ``` 29 | 30 | for example: 31 | 32 | ```sh 33 | npm uninstall -g webpack 34 | ``` 35 | 36 | and you can run this command from anywhere you want on your system because the folder where you currently are does not matter. 37 | -------------------------------------------------------------------------------- /documentation/0026-npm-packages-local-global/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: npm global or local packages 3 | description: 'When is a package best installed globally? Why?' 4 | author: flaviocopes 5 | --- 6 | 7 | The main difference between local and global packages is this: 8 | 9 | - **local packages** are installed in the directory where you run `npm install `, and they are put in the `node_modules` folder under this directory 10 | - **global packages** are all put in a single place in your system (exactly where depends on your setup), regardless of where you run `npm install -g ` 11 | 12 | In your code, they are both required in the same way: 13 | 14 | ```js 15 | require('package-name') 16 | ``` 17 | 18 | so when should you install in one way or another? 19 | 20 | In general, **all packages should be installed locally**. 21 | 22 | This makes sure you can have dozens of applications in your computer, all running a different version of each package if needed. 23 | 24 | Updating a global package would make all your projects use the new release, and as you can imagine this might cause nightmares in terms of maintenance, as some packages might break compatibility with further dependencies, and so on. 25 | 26 | All projects have their own local version of a package, even if this might appear like a waste of resources, it's minimal compared to the possible negative consequences. 27 | 28 | A package **should be installed globally** when it provides an executable command that you run from the shell (CLI), and it's reused across projects. 29 | 30 | You can also install executable commands locally and run them using npx, but some packages are just better installed globally. 31 | 32 | Great examples of popular global packages which you might know are 33 | 34 | - `npm` 35 | - `create-react-app` 36 | - `vue-cli` 37 | - `grunt-cli` 38 | - `mocha` 39 | - `react-native-cli` 40 | - `gatsby-cli` 41 | - `forever` 42 | - `nodemon` 43 | 44 | You probably have some packages installed globally already on your system. You can see them by running 45 | 46 | ```sh 47 | npm list -g --depth 0 48 | ``` 49 | 50 | on your command line. 51 | -------------------------------------------------------------------------------- /documentation/0027-npm-dependencies-devdependencies/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: npm dependencies and devDependencies 3 | description: 'When is a package a dependency, and when is it a dev dependency?' 4 | author: flaviocopes 5 | --- 6 | 7 | When you install an npm package using `npm install `, you are installing it as a **dependency**. 8 | 9 | The package is automatically listed in the package.json file, under the `dependencies` list (as of npm 5: before you had to manually specify `--save`). 10 | 11 | When you add the `-D` flag, or `--save-dev`, you are installing it as a development dependency, which adds it to the `devDependencies` list. 12 | 13 | Development dependencies are intended as development-only packages, that are unneeded in production. For example testing packages, webpack or Babel. 14 | 15 | When you go in production, if you type `npm install` and the folder contains a `package.json` file, they are installed, as npm assumes this is a development deploy. 16 | 17 | You need to set the `--production` flag (`npm install --production`) to avoid installing those development dependencies. 18 | -------------------------------------------------------------------------------- /documentation/0028-npx/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The npx Node Package Runner 3 | description: 'npx is a very cool way to run Node code, and provides many useful features' 4 | author: flaviocopes 5 | --- 6 | 7 | `npx` is a very powerful command that's been available in **npm** starting version 5.2, released in July 2017. 8 | 9 | > If you don't want to install npm, you can [install npx as a standalone package](https://www.npmjs.com/package/npx) 10 | 11 | `npx` lets you run code built with Node and published through the npm registry. 12 | 13 | ## Easily run local commands 14 | 15 | Node developers used to publish most of the executable commands as global packages, in order for them to be in the path and executable immediately. 16 | 17 | This was a pain because you could not really install different versions of the same command. 18 | 19 | Running `npx commandname` automatically finds the correct reference of the command inside the `node_modules` folder of a project, without needing to know the exact path, and without requiring the package to be installed globally and in the user's path. 20 | 21 | ## Installation-less command execution 22 | 23 | There is another great feature of `npm`, which is allowing to run commands without first installing them. 24 | 25 | This is pretty useful, mostly because: 26 | 27 | 1. you don't need to install anything 28 | 2. you can run different versions of the same command, using the syntax @version 29 | 30 | A typical demonstration of using `npx` is through the `cowsay` command. `cowsay` will print a cow saying what you wrote in the command. For example: 31 | 32 | `cowsay "Hello"` will print 33 | 34 | ``` 35 | _______ 36 | < Hello > 37 | ------- 38 | \ ^__^ 39 | \ (oo)\_______ 40 | (__)\ )\/\ 41 | ||----w | 42 | || || 43 | ``` 44 | 45 | Now, this if you have the `cowsay` command globally installed from npm previously, otherwise you'll get an error when you try to run the command. 46 | 47 | `npx` allows you to run that npm command without having it installed locally: 48 | 49 | ```bash 50 | npx cowsay "Hello" 51 | ``` 52 | 53 | will do the job. 54 | 55 | Now, this is a funny useless command. 56 | Other scenarios include: 57 | 58 | - running the `vue` CLI tool to create new applications and run them: `npx vue create my-vue-app` 59 | - creating a new React app using `create-react-app`: `npx create-react-app my-react-app` 60 | 61 | and many more. 62 | 63 | Once downloaded, the downloaded code will be wiped. 64 | 65 | ## Run some code using a different Node version 66 | 67 | Use the `@` to specify the version, and combine that with the [`node` npm package](https://www.npmjs.com/package/node): 68 | 69 | ```bash 70 | npx node@6 -v #v6.14.3 71 | npx node@8 -v #v8.11.3 72 | ``` 73 | 74 | This helps to avoid tools like `nvm` or the other Node version management tools. 75 | 76 | ## Run arbitrary code snippets directly from a URL 77 | 78 | `npx` does not limit you to the packages published on the npm registry. 79 | 80 | You can run code that sits in a GitHub gist, for example: 81 | 82 | ```bash 83 | npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32 84 | ``` 85 | 86 | Of course, you need to be careful when running code that you do not control, as with great power comes great responsibility. 87 | -------------------------------------------------------------------------------- /documentation/0029-node-event-loop/call-stack-first-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0029-node-event-loop/call-stack-first-example.png -------------------------------------------------------------------------------- /documentation/0029-node-event-loop/call-stack-second-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0029-node-event-loop/call-stack-second-example.png -------------------------------------------------------------------------------- /documentation/0029-node-event-loop/exception-call-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0029-node-event-loop/exception-call-stack.png -------------------------------------------------------------------------------- /documentation/0029-node-event-loop/execution-order-first-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0029-node-event-loop/execution-order-first-example.png -------------------------------------------------------------------------------- /documentation/0029-node-event-loop/execution-order-second-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0029-node-event-loop/execution-order-second-example.png -------------------------------------------------------------------------------- /documentation/0030-node-process-nexttick/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Understanding process.nextTick()' 3 | description: 'The Node.js process.nextTick function interacts with the event loop in a special way' 4 | author: flaviocopes 5 | --- 6 | 7 | As you try to understand the Node.js event loop, one important part of it is `process.nextTick()`. 8 | 9 | Every time the event loop takes a full trip, we call it a tick. 10 | 11 | When we pass a function to `process.nextTick()`, we instruct the engine to invoke this function at the end of the current operation, before the next event loop tick starts: 12 | 13 | ```js 14 | process.nextTick(() => { 15 | //do something 16 | }) 17 | ``` 18 | 19 | The event loop is busy processing the current function code. 20 | 21 | When this operation ends, the JS engine runs all the functions passed to `nextTick` calls during that operation. 22 | 23 | It's the way we can tell the JS engine to process a function asynchronously (after the current function), but as soon as possible, not queue it. 24 | 25 | Calling `setTimeout(() => {}, 0)` will execute the function at the end of next tick, much later than when using `nextTick()` which prioritizes the call and executes it just before the beginning of the next tick. 26 | 27 | Use `nextTick()` when you want to make sure that in the next event loop iteration that code is already executed. 28 | -------------------------------------------------------------------------------- /documentation/0031-node-setimmediate/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Understanding setImmediate()' 3 | description: 'The Node.js setImmediate function interacts with the event loop in a special way' 4 | author: flaviocopes 5 | --- 6 | 7 | When you want to execute some piece of code asynchronously, but as soon as possible, one option is to use the `setImmediate()` function provided by Node.js: 8 | 9 | ```js 10 | setImmediate(() => { 11 | //run something 12 | }) 13 | ``` 14 | 15 | Any function passed as the setImmediate() argument is a callback that's executed in the next iteration of the event loop. 16 | 17 | How is `setImmediate()` different from `setTimeout(() => {}, 0)` (passing a 0ms timeout), and from `process.nextTick()`? 18 | 19 | A function passed to `process.nextTick()` is going to be executed on the current iteration of the event loop, after the current operation ends. This means it will always execute before `setTimeout` and `setImmediate`. 20 | 21 | A `setTimeout()` callback with a 0ms delay is very similar to `setImmediate()`. The execution order will depend on various factors, but they will be both run in the next iteration of the event loop. 22 | -------------------------------------------------------------------------------- /documentation/0032-javascript-timers/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Discover JavaScript Timers 3 | description: 'When writing JavaScript code, you might want to delay the execution of a function. Learn how to use setTimeout and setInterval to schedule functions in the future' 4 | author: flaviocopes 5 | --- 6 | 7 | 8 | 9 | - [`setTimeout()`](#settimeout) 10 | - [Zero delay](#zero-delay) 11 | - [`setInterval()`](#setinterval) 12 | - [Recursive setTimeout](#recursive-settimeout) 13 | 14 | 15 | 16 | ## `setTimeout()` 17 | 18 | When writing JavaScript code, you might want to delay the execution of a function. 19 | 20 | This is the job of `setTimeout`. You specify a callback function to execute later, and a value expressing how later you want it to run, in milliseconds: 21 | 22 | ```js 23 | setTimeout(() => { 24 | // runs after 2 seconds 25 | }, 2000) 26 | 27 | setTimeout(() => { 28 | // runs after 50 milliseconds 29 | }, 50) 30 | ``` 31 | 32 | This syntax defines a new function. You can call whatever other function you want in there, or you can pass an existing function name, and a set of parameters: 33 | 34 | ```js 35 | const myFunction = (firstParam, secondParam) => { 36 | // do something 37 | } 38 | 39 | // runs after 2 seconds 40 | setTimeout(myFunction, 2000, firstParam, secondParam) 41 | ``` 42 | 43 | `setTimeout` returns the timer id. This is generally not used, but you can store this id, and clear it if you want to delete this scheduled function execution: 44 | 45 | ```js 46 | const id = setTimeout(() => { 47 | // should run after 2 seconds 48 | }, 2000) 49 | 50 | // I changed my mind 51 | clearTimeout(id) 52 | ``` 53 | 54 | ### Zero delay 55 | 56 | If you specify the timeout delay to `0`, the callback function will be executed as soon as possible, but after the current function execution: 57 | 58 | ```js 59 | setTimeout(() => { 60 | console.log('after ') 61 | }, 0) 62 | 63 | console.log(' before ') 64 | ``` 65 | 66 | will print `before after`. 67 | 68 | This is especially useful to avoid blocking the CPU on intensive tasks and let other functions be executed while performing a heavy calculation, by queuing functions in the scheduler. 69 | 70 | > Some browsers (IE and Edge) implement a `setImmediate()` method that does this same exact functionality, but it's not standard and [unavailable on other browsers](https://caniuse.com/#feat=setimmediate). But it's a standard function in Node.js. 71 | 72 | ## `setInterval()` 73 | 74 | `setInterval` is a function similar to `setTimeout`, with a difference: instead of running the callback function once, it will run it forever, at the specific time interval you specify (in milliseconds): 75 | 76 | ```js 77 | setInterval(() => { 78 | // runs every 2 seconds 79 | }, 2000) 80 | ``` 81 | 82 | The function above runs every 2 seconds unless you tell it to stop, using `clearInterval`, passing it the interval id that `setInterval` returned: 83 | 84 | ```js 85 | const id = setInterval(() => { 86 | // runs every 2 seconds 87 | }, 2000) 88 | 89 | clearInterval(id) 90 | ``` 91 | 92 | It's common to call `clearInterval` inside the setInterval callback function, to let it auto-determine if it should run again or stop. For example this code runs something unless App.somethingIWait has the value `arrived`: 93 | 94 | ```js 95 | const interval = setInterval(() => { 96 | if (App.somethingIWait === 'arrived') { 97 | clearInterval(interval) 98 | return 99 | } 100 | // otherwise do things 101 | }, 100) 102 | ``` 103 | 104 | ## Recursive setTimeout 105 | 106 | `setInterval` starts a function every n milliseconds, without any consideration about when a function finished its execution. 107 | 108 | If a function takes always the same amount of time, it's all fine: 109 | 110 | ![setInterval working fine](setinterval-ok.png) 111 | 112 | Maybe the function takes different execution times, depending on network conditions for example: 113 | 114 | ![setInterval varying duration](setinterval-varying-duration.png) 115 | 116 | And maybe one long execution overlaps the next one: 117 | 118 | ![setInterval overlapping](setinterval-overlapping.png) 119 | 120 | To avoid this, you can schedule a recursive setTimeout to be called when the callback function finishes: 121 | 122 | ```js 123 | const myFunction = () => { 124 | // do something 125 | 126 | setTimeout(myFunction, 1000) 127 | } 128 | 129 | setTimeout( 130 | myFunction() 131 | }, 1000) 132 | ``` 133 | 134 | to achieve this scenario: 135 | 136 | ![Recursive setTimeout](recursive-settimeout.png) 137 | 138 | `setTimeout` and `setInterval` are available in Node.js, through the [Timers module](https://nodejs.org/api/timers.html). 139 | 140 | Node.js also provides `setImmediate()`, which is equivalent to using `setTimeout(() => {}, 0)`, mostly used to work with the Node.js Event Loop. 141 | -------------------------------------------------------------------------------- /documentation/0032-javascript-timers/recursive-settimeout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0032-javascript-timers/recursive-settimeout.png -------------------------------------------------------------------------------- /documentation/0032-javascript-timers/setinterval-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0032-javascript-timers/setinterval-ok.png -------------------------------------------------------------------------------- /documentation/0032-javascript-timers/setinterval-overlapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0032-javascript-timers/setinterval-overlapping.png -------------------------------------------------------------------------------- /documentation/0032-javascript-timers/setinterval-varying-duration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0032-javascript-timers/setinterval-varying-duration.png -------------------------------------------------------------------------------- /documentation/0033-javascript-callbacks/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'JavaScript Asynchronous Programming and Callbacks' 3 | description: 'JavaScript is synchronous by default, and is single threaded. This means that code cannot create new threads and run in parallel. Find out what asynchronous code means and how it looks like' 4 | author: flaviocopes 5 | --- 6 | 7 | 8 | 9 | - [Asynchronicity in Programming Languages](#asynchronicity-in-programming-languages) 10 | - [JavaScript](#javascript) 11 | - [Callbacks](#callbacks) 12 | - [Handling errors in callbacks](#handling-errors-in-callbacks) 13 | - [The problem with callbacks](#the-problem-with-callbacks) 14 | - [Alternatives to callbacks](#alternatives-to-callbacks) 15 | 16 | 17 | 18 | ## Asynchronicity in Programming Languages 19 | 20 | Computers are asynchronous by design. 21 | 22 | Asynchronous means that things can happen independently of the main program flow. 23 | 24 | In the current consumer computers, every program runs for a specific time slot, and then it stops its execution to let another program continue its execution. This thing runs in a cycle so fast that's impossible to notice, and we think our computers run many programs simultaneously, but this is an illusion (except on multiprocessor machines). 25 | 26 | Programs internally use _interrupts_, a signal that's emitted to the processor to gain the attention of the system. 27 | 28 | I won't go into the internals of this, but just keep in mind that it's normal for programs to be asynchronous, and halt their execution until they need attention, and the computer can execute other things in the meantime. When a program is waiting for a response from the network, it cannot halt the processor until the request finishes. 29 | 30 | Normally, programming languages are synchronous, and some provide a way to manage asynchronicity, in the language or through libraries. C, Java, C#, PHP, Go, Ruby, Swift, Python, they are all synchronous by default. Some of them handle async by using threads, spawning a new process. 31 | 32 | ## JavaScript 33 | 34 | JavaScript is **synchronous** by default and is single threaded. This means that code cannot create new threads and run in parallel. 35 | 36 | Lines of code are executed in series, one after another, for example: 37 | 38 | ```js 39 | const a = 1 40 | const b = 2 41 | const c = a * b 42 | console.log(c) 43 | doSomething() 44 | ``` 45 | 46 | But JavaScript was born inside the browser, its main job, in the beginning, was to respond to user actions, like `onClick`, `onMouseOver`, `onChange`, `onSubmit` and so on. How could it do this with a synchronous programming model? 47 | 48 | The answer was in its environment. The **browser** provides a way to do it by providing a set of APIs that can handle this kind of functionality. 49 | 50 | More recently, Node.js introduced a non-blocking I/O environment to extend this concept to file access, network calls and so on. 51 | 52 | ## Callbacks 53 | 54 | You can't know when a user is going to click a button, so what you do is, you **define an event handler for the click event**. This event handler accepts a function, which will be called when the event is triggered: 55 | 56 | ```js 57 | document.getElementById('button').addEventListener('click', () => { 58 | //item clicked 59 | }) 60 | ``` 61 | 62 | This is the so-called **callback**. 63 | 64 | A callback is a simple function that's passed as a value to another function, and will only be executed when the event happens. We can do this because JavaScript has first-class functions, which can be assigned to variables and passed around to other functions (called **higher-order functions**) 65 | 66 | It's common to wrap all your client code in a `load` event listener on the `window` object, which runs the callback function only when the page is ready: 67 | 68 | ```js 69 | window.addEventListener('load', () => { 70 | //window loaded 71 | //do what you want 72 | }) 73 | ``` 74 | 75 | Callbacks are used everywhere, not just in DOM events. 76 | 77 | One common example is by using timers: 78 | 79 | ```js 80 | setTimeout(() => { 81 | // runs after 2 seconds 82 | }, 2000) 83 | ``` 84 | 85 | XHR requests also accept a callback, in this example by assigning a function to a property that will be called when a particular event occurs (in this case, the state of the request changes): 86 | 87 | ```js 88 | const xhr = new XMLHttpRequest() 89 | xhr.onreadystatechange = () => { 90 | if (xhr.readyState === 4) { 91 | xhr.status === 200 ? console.log(xhr.responseText) : console.error('error') 92 | } 93 | } 94 | xhr.open('GET', 'https://yoursite.com') 95 | xhr.send() 96 | ``` 97 | 98 | ## Handling errors in callbacks 99 | 100 | How do you handle errors with callbacks? One very common strategy is to use what Node.js adopted: the first parameter in any callback function is the error object: **error-first callbacks** 101 | 102 | If there is no error, the object is `null`. If there is an error, it contains some description of the error and other information. 103 | 104 | ```js 105 | fs.readFile('/file.json', (err, data) => { 106 | if (err !== null) { 107 | //handle error 108 | console.log(err) 109 | return 110 | } 111 | 112 | //no errors, process data 113 | console.log(data) 114 | }) 115 | ``` 116 | 117 | ## The problem with callbacks 118 | 119 | Callbacks are great for simple cases! 120 | 121 | However every callback adds a level of nesting, and when you have lots of callbacks, the code starts to be complicated very quickly: 122 | 123 | ```js 124 | window.addEventListener('load', () => { 125 | document.getElementById('button').addEventListener('click', () => { 126 | setTimeout(() => { 127 | items.forEach(item => { 128 | //your code here 129 | }) 130 | }, 2000) 131 | }) 132 | }) 133 | ``` 134 | 135 | This is just a simple 4-levels code, but I've seen much more levels of nesting and it's not fun. 136 | 137 | How do we solve this? 138 | 139 | ## Alternatives to callbacks 140 | 141 | Starting with ES6, JavaScript introduced several features that help us with asynchronous code that do not involve using callbacks: Promises (ES6) and Async/Await (ES2017). 142 | -------------------------------------------------------------------------------- /documentation/0035-javascript-async-await/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Modern Asynchronous JavaScript with Async and Await' 3 | description: 'Discover the modern approach to asynchronous functions in JavaScript. JavaScript evolved in a very short time from callbacks to Promises, and since ES2017 asynchronous JavaScript is even simpler with the async/await syntax' 4 | author: flaviocopes 5 | --- 6 | 7 | 8 | 9 | - [Introduction](#introduction) 10 | - [Why were async/await introduced?](#why-were-asyncawait-introduced) 11 | - [How it works](#how-it-works) 12 | - [A quick example](#a-quick-example) 13 | - [Promise all the things](#promise-all-the-things) 14 | - [The code is much simpler to read](#the-code-is-much-simpler-to-read) 15 | - [Multiple async functions in series](#multiple-async-functions-in-series) 16 | - [Easier debugging](#easier-debugging) 17 | 18 | 19 | 20 | ## Introduction 21 | 22 | JavaScript evolved in a very short time from callbacks to promises (ES2015), and since ES2017 asynchronous JavaScript is even simpler with the async/await syntax. 23 | 24 | Async functions are a combination of promises and generators, and basically, they are a higher level abstraction over promises. Let me repeat: **async/await is built on promises**. 25 | 26 | ## Why were async/await introduced? 27 | 28 | They reduce the boilerplate around promises, and the "don't break the chain" limitation of chaining promises. 29 | 30 | When Promises were introduced in ES2015, they were meant to solve a problem with asynchronous code, and they did, but over the 2 years that separated ES2015 and ES2017, it was clear that _promises could not be the final solution_. 31 | 32 | Promises were introduced to solve the famous _callback hell_ problem, but they introduced complexity on their own, and syntax complexity. 33 | 34 | They were good primitives around which a better syntax could be exposed to the developers, so when the time was right we got **async functions**. 35 | 36 | They make the code look like it's synchronous, but it's asynchronous and non-blocking behind the scenes. 37 | 38 | ## How it works 39 | 40 | An async function returns a promise, like in this example: 41 | 42 | ```js 43 | const doSomethingAsync = () => { 44 | return new Promise(resolve => { 45 | setTimeout(() => resolve('I did something'), 3000) 46 | }) 47 | } 48 | ``` 49 | 50 | When you want to **call** this function you prepend `await`, and **the calling code will stop until the promise is resolved or rejected**. One caveat: the client function must be defined as `async`. Here's an example: 51 | 52 | ```js 53 | const doSomething = async () => { 54 | console.log(await doSomethingAsync()) 55 | } 56 | ``` 57 | 58 | ## A quick example 59 | 60 | This is a simple example of async/await used to run a function asynchronously: 61 | 62 | ```js 63 | const doSomethingAsync = () => { 64 | return new Promise(resolve => { 65 | setTimeout(() => resolve('I did something'), 3000) 66 | }) 67 | } 68 | 69 | const doSomething = async () => { 70 | console.log(await doSomethingAsync()) 71 | } 72 | 73 | console.log('Before') 74 | doSomething() 75 | console.log('After') 76 | ``` 77 | 78 | The above code will print the following to the browser console: 79 | 80 | ``` 81 | Before 82 | After 83 | I did something //after 3s 84 | ``` 85 | 86 | ## Promise all the things 87 | 88 | Prepending the `async` keyword to any function means that the function will return a promise. 89 | 90 | Even if it's not doing so explicitly, it will internally make it return a promise. 91 | 92 | This is why this code is valid: 93 | 94 | ```js 95 | const aFunction = async () => { 96 | return 'test' 97 | } 98 | 99 | aFunction().then(alert) // This will alert 'test' 100 | ``` 101 | 102 | and it's the same as: 103 | 104 | ```js 105 | const aFunction = async () => { 106 | return Promise.resolve('test') 107 | } 108 | 109 | aFunction().then(alert) // This will alert 'test' 110 | ``` 111 | 112 | ## The code is much simpler to read 113 | 114 | As you can see in the example above, our code looks very simple. Compare it to code using plain promises, with chaining and callback functions. 115 | 116 | And this is a very simple example, the major benefits will arise when the code is much more complex. 117 | 118 | For example here's how you would get a JSON resource, and parse it, using promises: 119 | 120 | ```js 121 | const getFirstUserData = () => { 122 | return fetch('/users.json') // get users list 123 | .then(response => response.json()) // parse JSON 124 | .then(users => users[0]) // pick first user 125 | .then(user => fetch(`/users/${user.name}`)) // get user data 126 | .then(userResponse => response.json()) // parse JSON 127 | } 128 | 129 | getFirstUserData() 130 | ``` 131 | 132 | And here is the same functionality provided using await/async: 133 | 134 | ```js 135 | const getFirstUserData = async () => { 136 | const response = await fetch('/users.json') // get users list 137 | const users = await response.json() // parse JSON 138 | const user = users[0] // pick first user 139 | const userResponse = await fetch(`/users/${user.name}`) // get user data 140 | const userData = await user.json() // parse JSON 141 | return userData 142 | } 143 | 144 | getFirstUserData() 145 | ``` 146 | 147 | ## Multiple async functions in series 148 | 149 | Async functions can be chained very easily, and the syntax is much more readable than with plain promises: 150 | 151 | ```js 152 | const promiseToDoSomething = () => { 153 | return new Promise(resolve => { 154 | setTimeout(() => resolve('I did something'), 10000) 155 | }) 156 | } 157 | 158 | const watchOverSomeoneDoingSomething = async () => { 159 | const something = await promiseToDoSomething() 160 | return something + ' and I watched' 161 | } 162 | 163 | const watchOverSomeoneWatchingSomeoneDoingSomething = async () => { 164 | const something = await watchOverSomeoneDoingSomething() 165 | return something + ' and I watched as well' 166 | } 167 | 168 | watchOverSomeoneWatchingSomeoneDoingSomething().then(res => { 169 | console.log(res) 170 | }) 171 | ``` 172 | 173 | Will print: 174 | 175 | ``` 176 | I did something and I watched and I watched as well 177 | ``` 178 | 179 | ## Easier debugging 180 | 181 | Debugging promises is hard because the debugger will not step over asynchronous code. 182 | 183 | Async/await makes this very easy because to the compiler it's just like synchronous code. 184 | -------------------------------------------------------------------------------- /documentation/0036-node-event-emitter/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The Node Event emitter 3 | description: 'How to work with custom events in Node' 4 | author: flaviocopes 5 | --- 6 | 7 | If you worked with JavaScript in the browser, you know how much of the interaction of the user is handled through events: mouse clicks, keyboard button presses, reacting to mouse movements, and so on. 8 | 9 | On the backend side, Node offers us the option to build a similar system using the [`events` module](https://nodejs.org/api/events.html). 10 | 11 | This module, in particular, offers the `EventEmitter` class, which we'll use to handle our events. 12 | 13 | You initialize that using 14 | 15 | ```js 16 | const eventEmitter = require('events').EventEmitter() 17 | ``` 18 | 19 | This object exposes, among many others, the `on` and `emit` methods. 20 | 21 | - `emit` is used to trigger an event 22 | - `on` is used to add a callback function that's going to be executed when the event is triggered 23 | 24 | For example, let's create a `start` event, and as a matter of providing a sample, we react to that by just logging to the console: 25 | 26 | ```js 27 | eventEmitter.on('start', () => { 28 | console.log('started') 29 | }) 30 | ``` 31 | 32 | When we run 33 | 34 | ```js 35 | eventEmitter.emit('start') 36 | ``` 37 | 38 | the event handler function is triggered, and we get the console log. 39 | 40 | You can pass arguments to the event handler by passing them as additional arguments to `emit()`: 41 | 42 | ```js 43 | eventEmitter.on('start', number => { 44 | console.log(`started ${number}`) 45 | }) 46 | 47 | eventEmitter.emit('start', 23) 48 | ``` 49 | 50 | Multiple arguments: 51 | 52 | ```js 53 | eventEmitter.on('start', (start, end) => { 54 | console.log(`started from ${start} to ${end}`) 55 | }) 56 | 57 | eventEmitter.emit('start', 1, 100) 58 | ``` 59 | 60 | The EventEmitter object also exposes several other methods to interact with events, like 61 | 62 | - `once()`: add a one-time listener 63 | - `removeListener()` / `off()`: remove an event listener from an event 64 | - `removeAllListeners()`: remove all listeners for an event 65 | 66 | You can read all their details on the events module page at 67 | -------------------------------------------------------------------------------- /documentation/0037-node-http-server/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Build an HTTP Server' 3 | description: 'How to build an HTTP server with Node.js' 4 | author: flaviocopes 5 | --- 6 | 7 | Here is a sample Hello World HTTP web server: 8 | 9 | ```js 10 | const http = require('http') 11 | 12 | const port = 3000 13 | 14 | const server = http.createServer((req, res) => { 15 | res.statusCode = 200 16 | res.setHeader('Content-Type', 'text/plain') 17 | res.end('Hello World\n') 18 | }) 19 | 20 | server.listen(port, () => { 21 | console.log(`Server running at http://${hostname}:${port}/`) 22 | }) 23 | ``` 24 | 25 | Let's analyze it briefly. We include the [`http` module](https://nodejs.org/api/http.html). 26 | 27 | We use the module to create an HTTP server. 28 | 29 | The server is set to listen on the specified port, `3000`. When the server is ready, the `listen` callback function is called. 30 | 31 | The callback function we pass is the one that's going to be executed upon every request that comes in. Whenever a new request is received, the [`request` event](https://nodejs.org/api/http.html#http_event_request) is called, providing two objects: a request (an [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) object) and a response (an [`http.ServerResponse`](https://nodejs.org/api/http.html#http_class_http_serverresponse) object). 32 | 33 | `request` provides the request details. Through it, we access the request headers and request data. 34 | 35 | `response` is used to populate the data we're going to return to the client. 36 | 37 | In this case with 38 | 39 | ```js 40 | res.statusCode = 200 41 | ``` 42 | 43 | we set the statusCode property to 200, to indicate a successful response. 44 | 45 | We also set the Content-Type header: 46 | 47 | ```js 48 | res.setHeader('Content-Type', 'text/plain') 49 | ``` 50 | 51 | and we end close the response, adding the content as an argument to `end()`: 52 | 53 | ```js 54 | res.end('Hello World\n') 55 | ``` 56 | -------------------------------------------------------------------------------- /documentation/0038-node-make-http-requests/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Making HTTP requests with Node' 3 | description: 'How to perform HTTP requests with Node.js using GET, POST, PUT and DELETE' 4 | author: flaviocopes 5 | --- 6 | 7 | ## Perform a GET Request 8 | 9 | ```js 10 | const https = require('https') 11 | const options = { 12 | hostname: 'whatever.com', 13 | port: 443, 14 | path: '/todos', 15 | method: 'GET' 16 | } 17 | 18 | const req = https.request(options, res => { 19 | console.log(`statusCode: ${res.statusCode}`) 20 | 21 | res.on('data', d => { 22 | process.stdout.write(d) 23 | }) 24 | }) 25 | 26 | req.on('error', error => { 27 | console.error(error) 28 | }) 29 | 30 | req.end() 31 | ``` 32 | 33 | ## Perform a POST Request 34 | 35 | ```js 36 | const https = require('https') 37 | 38 | const data = JSON.stringify({ 39 | todo: 'Buy the milk' 40 | }) 41 | 42 | const options = { 43 | hostname: 'whatever.com', 44 | port: 443, 45 | path: '/todos', 46 | method: 'POST', 47 | headers: { 48 | 'Content-Type': 'application/json', 49 | 'Content-Length': data.length 50 | } 51 | } 52 | 53 | const req = https.request(options, res => { 54 | console.log(`statusCode: ${res.statusCode}`) 55 | 56 | res.on('data', d => { 57 | process.stdout.write(d) 58 | }) 59 | }) 60 | 61 | req.on('error', error => { 62 | console.error(error) 63 | }) 64 | 65 | req.write(data) 66 | req.end() 67 | ``` 68 | 69 | ## PUT and DELETE 70 | 71 | PUT and DELETE requests use the same POST request format, and just change the `options.method` value. 72 | -------------------------------------------------------------------------------- /documentation/0039-node-http-post/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Make an HTTP POST request using Node 3 | description: 'Find out how to make an HTTP POST request using Node' 4 | author: flaviocopes 5 | --- 6 | 7 | There are many ways to perform an HTTP POST request in Node, depending on the abstraction level you want to use. 8 | 9 | The simplest way to perform an HTTP request using Node is to use the Axios library: 10 | 11 | ```js 12 | const axios = require('axios') 13 | 14 | axios 15 | .post('https://whatever.com/todos', { 16 | todo: 'Buy the milk' 17 | }) 18 | .then(res => { 19 | console.log(`statusCode: ${res.statusCode}`) 20 | console.log(res) 21 | }) 22 | .catch(error => { 23 | console.error(error) 24 | }) 25 | ``` 26 | 27 | Another way is to use the [Request library](https://github.com/request/request): 28 | 29 | ```js 30 | const request = require('request') 31 | 32 | request.post( 33 | 'https://whatever.com/todos', 34 | { 35 | json: { 36 | todo: 'Buy the milk' 37 | } 38 | }, 39 | (error, res, body) => { 40 | if (error) { 41 | console.error(error) 42 | return 43 | } 44 | console.log(`statusCode: ${res.statusCode}`) 45 | console.log(body) 46 | } 47 | ) 48 | ``` 49 | 50 | The 2 ways highlighted up to now require the use of a 3rd part library. 51 | 52 | A POST request is possible just using the Node standard modules, although it's more verbose than the two preceding options: 53 | 54 | ```js 55 | const https = require('https') 56 | 57 | const data = JSON.stringify({ 58 | todo: 'Buy the milk' 59 | }) 60 | 61 | const options = { 62 | hostname: 'whatever.com', 63 | port: 443, 64 | path: '/todos', 65 | method: 'POST', 66 | headers: { 67 | 'Content-Type': 'application/json', 68 | 'Content-Length': data.length 69 | } 70 | } 71 | 72 | const req = https.request(options, res => { 73 | console.log(`statusCode: ${res.statusCode}`) 74 | 75 | res.on('data', d => { 76 | process.stdout.write(d) 77 | }) 78 | }) 79 | 80 | req.on('error', error => { 81 | console.error(error) 82 | }) 83 | 84 | req.write(data) 85 | req.end() 86 | ``` 87 | -------------------------------------------------------------------------------- /documentation/0040a-node-request-data/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Get HTTP request body data using Node 3 | description: 'Find out how to extract the data sent as JSON through an HTTP request body using Node' 4 | author: flaviocopes 5 | --- 6 | 7 | Here is how you can extract the data that was sent as JSON in the request body. 8 | 9 | If you are using Express, that's quite simple: use the `body-parser` Node module. 10 | 11 | For example, to get the body of this request: 12 | 13 | ```js 14 | const axios = require('axios') 15 | 16 | axios.post('https://whatever.com/todos', { 17 | todo: 'Buy the milk' 18 | }) 19 | ``` 20 | 21 | This is the matching server-side code: 22 | 23 | ```js 24 | const bodyParser = require('body-parser') 25 | 26 | app.use( 27 | bodyParser.urlencoded({ 28 | extended: true 29 | }) 30 | ) 31 | 32 | app.use(bodyParser.json()) 33 | 34 | app.post('/endpoint', (req, res) => { 35 | console.log(req.body.todo) 36 | }) 37 | ``` 38 | 39 | If you're not using Express and you want to do this in vanilla Node, you need to do a bit more work, of course, as Express abstracts a lot of this for you. 40 | 41 | The key thing to understand is that when you initialize the HTTP server using `http.createServer()`, the callback is called when the server got all the HTTP headers, but not the request body. 42 | 43 | The `request` object passed in the connection callback is a stream. 44 | 45 | So, we must listen for the body content to be processed, and it's processed in chunks. 46 | 47 | We first get the data by listening to the stream `data` events, and when the data ends, the stream `end` event is called, once: 48 | 49 | ```js 50 | const server = http.createServer((req, res) => { 51 | // we can access HTTP headers 52 | req.on('data', chunk => { 53 | console.log(`Data chunk available: ${chunk}`) 54 | }) 55 | req.on('end', () => { 56 | //end of data 57 | }) 58 | }) 59 | ``` 60 | 61 | So to access the data, assuming we expect to receive a string, we must put it into an array: 62 | 63 | ```js 64 | const server = http.createServer((req, res) => { 65 | let data = [] 66 | req.on('data', chunk => { 67 | data.push(chunk) 68 | }) 69 | req.on('end', () => { 70 | JSON.parse(data).todo // 'Buy the milk' 71 | }) 72 | }) 73 | ``` 74 | -------------------------------------------------------------------------------- /documentation/0040b-node-file-descriptors/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Working with file descriptors in Node' 3 | description: 'How to interact with file descriptors using Node' 4 | author: flaviocopes 5 | --- 6 | 7 | Before you're able to interact with a file that sits in your filesystem, you must get a file descriptor. 8 | 9 | A file descriptor is what's returned by opening the file using the `open()` method offered by the `fs` module: 10 | 11 | ```js 12 | const fs = require('fs') 13 | 14 | fs.open('/Users/joe/test.txt', 'r', (err, fd) => { 15 | //fd is our file descriptor 16 | }) 17 | ``` 18 | 19 | Notice the `r` we used as the second parameter to the `fs.open()` call. 20 | 21 | That flag means we open the file for reading. 22 | 23 | Other flags you'll commonly use are 24 | 25 | - `r+` open the file for reading and writing 26 | - `w+` open the file for reading and writing, positioning the stream at the beginning of the file. The file is created if not existing 27 | - `a` open the file for writing, positioning the stream at the end of the file. The file is created if not existing 28 | - `a+` open the file for reading and writing, positioning the stream at the end of the file. The file is created if not existing 29 | 30 | You can also open the file by using the `fs.openSync` method, which instead of providing the file descriptor object in a callback, it returns it: 31 | 32 | ```js 33 | const fs = require('fs') 34 | 35 | try { 36 | const fd = fs.openSync('/Users/joe/test.txt', 'r') 37 | } catch (err) { 38 | console.error(err) 39 | } 40 | ``` 41 | 42 | Once you get the file descriptor, in whatever way you choose, you can perform all the operations that require it, like calling `fs.open()` and many other operations that interact with the filesystem. 43 | -------------------------------------------------------------------------------- /documentation/0041-node-file-stats/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Node file stats' 3 | description: 'How to get the details of a file using Node' 4 | author: flaviocopes 5 | --- 6 | 7 | Every file comes with a set of details that we can inspect using Node. 8 | 9 | In particular, using the `stat()` method provided by the `fs` module. 10 | 11 | You call it passing a file path, and once Node gets the file details it will call the callback function you pass, with 2 parameters: an error message, and the file stats: 12 | 13 | ```js 14 | const fs = require('fs') 15 | fs.stat('/Users/joe/test.txt', (err, stats) => { 16 | if (err) { 17 | console.error(err) 18 | return 19 | } 20 | //we have access to the file stats in `stats` 21 | }) 22 | ``` 23 | 24 | Node provides also a sync method, which blocks the thread until the file stats are ready: 25 | 26 | ```js 27 | const fs = require('fs') 28 | try { 29 | const stats = fs.stat('/Users/joe/test.txt') 30 | } catch (err) { 31 | console.error(err) 32 | } 33 | ``` 34 | 35 | The file information is included in the stats variable. What kind of information can we extract using the stats? 36 | 37 | A lot, including: 38 | 39 | - if the file is a directory or a file, using `stats.isFile()` and `stats.isDirectory()` 40 | - if the file is a symbolic link using `stats.isSymbolicLink()` 41 | - the file size in bytes using `stats.size`. 42 | 43 | There are other advanced methods, but the bulk of what you'll use in your day-to-day programming is this. 44 | 45 | ```js 46 | const fs = require('fs') 47 | fs.stat('/Users/joe/test.txt', (err, stats) => { 48 | if (err) { 49 | console.error(err) 50 | return 51 | } 52 | 53 | stats.isFile() //true 54 | stats.isDirectory() //false 55 | stats.isSymbolicLink() //false 56 | stats.size //1024000 //= 1MB 57 | }) 58 | ``` 59 | -------------------------------------------------------------------------------- /documentation/0042-node-file-paths/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Node File Paths' 3 | description: 'How to interact with file paths and manipulate them in Node' 4 | author: flaviocopes 5 | --- 6 | 7 | 8 | 9 | - [Getting information out of a path](#getting-information-out-of-a-path) 10 | - [Working with paths](#working-with-paths) 11 | 12 | 13 | 14 | Every file in the system has a path. 15 | 16 | On Linux and macOS, a path might look like: 17 | 18 | `/users/joe/file.txt` 19 | 20 | while Windows computers are different, and have a structure such as: 21 | 22 | `C:\users\joe\file.txt` 23 | 24 | You need to pay attention when using paths in your applications, as this difference must be taken into account. 25 | 26 | You include this module in your files using 27 | 28 | ```js 29 | const path = require('path') 30 | ``` 31 | 32 | and you can start using its methods. 33 | 34 | ## Getting information out of a path 35 | 36 | Given a path, you can extract information out of it using those methods: 37 | 38 | - `dirname`: get the parent folder of a file 39 | - `basename`: get the filename part 40 | - `extname`: get the file extension 41 | 42 | Example: 43 | 44 | ```js 45 | const notes = '/users/joe/notes.txt' 46 | 47 | path.dirname(notes) // /users/joe 48 | path.basename(notes) // notes.txt 49 | path.extname(notes) // .txt 50 | ``` 51 | 52 | You can get the file name without the extension by specifying a second argument to `basename`: 53 | 54 | ```js 55 | path.basename(notes, path.extname(notes)) //notes 56 | ``` 57 | 58 | ## Working with paths 59 | 60 | You can join two or more parts of a path by using `path.join()`: 61 | 62 | ```js 63 | const name = 'joe' 64 | path.join('/', 'users', name, 'notes.txt') //'/users/joe/notes.txt' 65 | ``` 66 | 67 | You can get the absolute path calculation of a relative path using `path.resolve()`: 68 | 69 | ```js 70 | path.resolve('joe.txt') //'/Users/joe/joe.txt' if run from my home folder 71 | ``` 72 | 73 | In this case Node will simply append `/joe.txt` to the current working directory. If you specify a second parameter folder, `resolve` will use the first as a base for the second: 74 | 75 | ```js 76 | path.resolve('tmp', 'joe.txt') //'/Users/joe/tmp/joe.txt' if run from my home folder 77 | ``` 78 | 79 | If the first parameter starts with a slash, that means it's an absolute path: 80 | 81 | ```js 82 | path.resolve('/etc', 'joe.txt') //'/etc/joe.txt' 83 | ``` 84 | 85 | `path.normalize()` is another useful function, that will try and calculate the actual path, when it contains relative specifiers like `.` or `..`, or double slashes: 86 | 87 | ```js 88 | path.normalize('/users/joe/..//test.txt') ///users/test.txt 89 | ``` 90 | 91 | **Both resolve and normalize will not check if the path exists**. They just calculate a path based on the information they got. 92 | -------------------------------------------------------------------------------- /documentation/0043-node-reading-files/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Reading files with Node' 3 | description: 'How to read files using Node' 4 | author: flaviocopes 5 | --- 6 | 7 | The simplest way to read a file in Node is to use the `fs.readFile()` method, passing it the file path and a callback function that will be called with the file data (and the error): 8 | 9 | ```js 10 | const fs = require('fs') 11 | 12 | fs.readFile('/Users/joe/test.txt', (err, data) => { 13 | if (err) { 14 | console.error(err) 15 | return 16 | } 17 | console.log(data) 18 | }) 19 | ``` 20 | 21 | Alternatively, you can use the synchronous version `fs.readFileSync()`: 22 | 23 | ```js 24 | const fs = require('fs') 25 | 26 | try { 27 | const data = fs.readFileSync('/Users/joe/test.txt', 'utf8') 28 | console.log(data) 29 | } catch (err) { 30 | console.error(err) 31 | } 32 | ``` 33 | 34 | The default encoding is utf8, but you can specify a custom encoding using a a second parameter. 35 | 36 | Both `fs.readFile()` and `fs.readFileSync()` read the full content of the file in memory before returning the data. 37 | 38 | This means that big files are going to have a major impact on your memory consumption and speed of execution of the program. 39 | 40 | In this case, a better option is to read the file content using streams. 41 | -------------------------------------------------------------------------------- /documentation/0044-node-writing-files/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Writing files with Node' 3 | description: 'How to write files using Node' 4 | author: flaviocopes 5 | --- 6 | 7 | The easiest way to write to files in Node.js is to use the `fs.writeFile()` API. 8 | 9 | Example: 10 | 11 | ```js 12 | const fs = require('fs') 13 | 14 | const content = 'Some content!' 15 | 16 | fs.writeFile('/Users/joe/test.txt', content, err => { 17 | if (err) { 18 | console.error(err) 19 | return 20 | } 21 | //file written successfully 22 | }) 23 | ``` 24 | 25 | Alternatively, you can use the synchronous version `fs.writeFileSync()`: 26 | 27 | ```js 28 | const fs = require('fs') 29 | 30 | const content = 'Some content!' 31 | 32 | try { 33 | const data = fs.writeFileSync('/Users/joe/test.txt', content) 34 | //file written successfully 35 | } catch (err) { 36 | console.error(err) 37 | } 38 | ``` 39 | 40 | By default, this API will **replace the contents of the file** if it does already exist. 41 | 42 | You can modify the default by specifying a flag: 43 | 44 | ```js 45 | fs.writeFile('/Users/joe/test.txt', content, { flag: 'a+' }, err => {}) 46 | ``` 47 | 48 | The flags you'll likely use are 49 | 50 | - `r+` open the file for reading and writing 51 | - `w+` open the file for reading and writing, positioning the stream at the beginning of the file. The file is created if not existing 52 | - `a` open the file for writing, positioning the stream at the end of the file. The file is created if not existing 53 | - `a+` open the file for reading and writing, positioning the stream at the end of the file. The file is created if not existing 54 | 55 | (you can find more flags at ) 56 | 57 | ## Append to a file 58 | 59 | A handy method to append content to the end of a file is `fs.appendFile()` (and its `fs.appendFileSync()` counterpart): 60 | 61 | ```js 62 | const content = 'Some content!' 63 | 64 | fs.appendFile('file.log', content, err => { 65 | if (err) { 66 | console.error(err) 67 | return 68 | } 69 | //done! 70 | }) 71 | ``` 72 | 73 | ## Using streams 74 | 75 | All those methods write the full content to the file before returning the control back to your program (in the async version, this means executing the callback) 76 | 77 | In this case, a better option is to write the file content using streams. 78 | -------------------------------------------------------------------------------- /documentation/0045-node-folders/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Working with folders in Node' 3 | description: 'How to interact with folders using Node' 4 | author: flaviocopes 5 | --- 6 | 7 | The Node.js `fs` core module provides many handy methods you can use to work with folders. 8 | 9 | ## Check if a folder exists 10 | 11 | Use `fs.access()` to check if the folder exists and Node can access it with its permissions. 12 | 13 | ## Create a new folder 14 | 15 | Use `fs.mkdir()` or `fs.mkdirSync()` to create a new folder. 16 | 17 | ```js 18 | const fs = require('fs') 19 | 20 | const folderName = '/Users/joe/test' 21 | 22 | try { 23 | if (!fs.existsSync(dir)) { 24 | fs.mkdirSync(dir) 25 | } 26 | } catch (err) { 27 | console.error(err) 28 | } 29 | ``` 30 | 31 | ## Read the content of a directory 32 | 33 | Use `fs.readdir()` or `fs.readdirSync` to read the contents of a directory. 34 | 35 | This piece of code reads the content of a folder, both files and subfolders, and returns their relative path: 36 | 37 | ```js 38 | const fs = require('fs') 39 | const path = require('path') 40 | 41 | const folderPath = '/Users/joe' 42 | 43 | fs.readdirSync(folderPath) 44 | ``` 45 | 46 | You can get the full path: 47 | 48 | ```js 49 | fs.readdirSync(folderPath).map(fileName => { 50 | return path.join(folderPath, fileName) 51 | }) 52 | ``` 53 | 54 | You can also filter the results to only return the files, and exclude the folders: 55 | 56 | ```js 57 | const isFile = fileName => { 58 | return fs.lstatSync(fileName).isFile() 59 | } 60 | 61 | fs.readdirSync(folderPath).map(fileName => { 62 | return path.join(folderPath, fileName) 63 | }) 64 | .filter(isFile) 65 | ``` 66 | 67 | ## Rename a folder 68 | 69 | Use `fs.rename()` or `fs.renameSync()` to rename folder. The first parameter is the current path, the second the new path: 70 | 71 | ```js 72 | const fs = require('fs') 73 | 74 | fs.rename('/Users/joe', '/Users/roger', err => { 75 | if (err) { 76 | console.error(err) 77 | return 78 | } 79 | //done 80 | }) 81 | ``` 82 | 83 | `fs.renameSync()` is the synchronous version: 84 | 85 | ```js 86 | const fs = require('fs') 87 | 88 | try { 89 | fs.renameSync('/Users/joe', '/Users/roger') 90 | } catch (err) { 91 | console.error(err) 92 | } 93 | ``` 94 | 95 | ## Remove a folder 96 | 97 | Use `fs.rmdir()` or `fs.rmdirSync()` to remove a folder. 98 | 99 | Removing a folder that has content can be more complicated than you need. 100 | 101 | In this case it's best to install the `fs-extra` module, which is very popular and well maintained. It's a drop-in replacement of the `fs` module, which provides more features on top of it. 102 | 103 | In this case the `remove()` method is what you want. 104 | 105 | Install it using 106 | 107 | `npm install fs-extra` 108 | 109 | and use it like this: 110 | 111 | ```js 112 | const fs = require('fs-extra') 113 | 114 | const folder = '/Users/joe' 115 | 116 | fs.remove(folder, err => { 117 | console.error(err) 118 | }) 119 | ``` 120 | 121 | It can also be used with promises: 122 | 123 | ```js 124 | fs.remove(folder) 125 | .then(() => { 126 | //done 127 | }) 128 | .catch(err => { 129 | console.error(err) 130 | }) 131 | ``` 132 | 133 | or with async/await: 134 | 135 | ```js 136 | async function removeFolder(folder) { 137 | try { 138 | await fs.remove(folder) 139 | //done 140 | } catch (err) { 141 | console.error(err) 142 | } 143 | } 144 | 145 | const folder = '/Users/joe' 146 | removeFolder(folder) 147 | ``` 148 | -------------------------------------------------------------------------------- /documentation/0046-node-module-fs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'The Node fs module' 3 | description: 'The fs module of Node.js provides useful functions to interact with the file system' 4 | author: flaviocopes 5 | --- 6 | 7 | The `fs` module provides a lot of very useful functionality to access and interact with the file system. 8 | 9 | There is no need to install it. Being part of the Node core, it can be used by simply requiring it: 10 | 11 | ```js 12 | const fs = require('fs') 13 | ``` 14 | 15 | Once you do so, you have access to all its methods, which include: 16 | 17 | - `fs.access()`: check if the file exists and Node can access it with its permissions 18 | - `fs.appendFile()`: append data to a file. If the file does not exist, it's created 19 | - `fs.chmod()`: change the permissions of a file specified by the filename passed. Related: `fs.lchmod()`, `fs.fchmod()` 20 | - `fs.chown()`: change the owner and group of a file specified by the filename passed. Related: `fs.fchown()`, `fs.lchown()` 21 | - `fs.close()`: close a file descriptor 22 | - `fs.copyFile()`: copies a file 23 | - `fs.createReadStream()`: create a readable file stream 24 | - `fs.createWriteStream()`: create a writable file stream 25 | - `fs.link()`: create a new hard link to a file 26 | - `fs.mkdir()`: create a new folder 27 | - `fs.mkdtemp()`: create a temporary directory 28 | - `fs.open()`: set the file mode 29 | - `fs.readdir()`: read the contents of a directory 30 | - `fs.readFile()`: read the content of a file. Related: `fs.read()` 31 | - `fs.readlink()`: read the value of a symbolic link 32 | - `fs.realpath()`: resolve relative file path pointers (`.`, `..`) to the full path 33 | - `fs.rename()`: rename a file or folder 34 | - `fs.rmdir()`: remove a folder 35 | - `fs.stat()`: returns the status of the file identified by the filename passed. Related: `fs.fstat()`, `fs.lstat()` 36 | - `fs.symlink()`: create a new symbolic link to a file 37 | - `fs.truncate()`: truncate to the specified length the file identified by the filename passed. Related: `fs.ftruncate()` 38 | - `fs.unlink()`: remove a file or a symbolic link 39 | - `fs.unwatchFile()`: stop watching for changes on a file 40 | - `fs.utimes()`: change the timestamp of the file identified by the filename passed. Related: `fs.futimes()` 41 | - `fs.watchFile()`: start watching for changes on a file. Related: `fs.watch()` 42 | - `fs.writeFile()`: write data to a file. Related: `fs.write()` 43 | 44 | One peculiar thing about the `fs` module is that all the methods are asynchronous by default, but they can also work synchronously by appending `Sync`. 45 | 46 | For example: 47 | 48 | - `fs.rename()` 49 | - `fs.renameSync()` 50 | - `fs.write()` 51 | - `fs.writeSync()` 52 | 53 | This makes a huge difference in your application flow. 54 | 55 | > Node 10 includes [experimental support](https://nodejs.org/api/fs.html#fs_fs_promises_api) for a promise based API 56 | 57 | For example let's examine the `fs.rename()` method. The asynchronous API is used with a callback: 58 | 59 | ```js 60 | const fs = require('fs') 61 | 62 | fs.rename('before.json', 'after.json', err => { 63 | if (err) { 64 | return console.error(err) 65 | } 66 | 67 | //done 68 | }) 69 | ``` 70 | 71 | A synchronous API can be used like this, with a try/catch block to handle errors: 72 | 73 | ```js 74 | const fs = require('fs') 75 | 76 | try { 77 | fs.renameSync('before.json', 'after.json') 78 | //done 79 | } catch (err) { 80 | console.error(err) 81 | } 82 | ``` 83 | 84 | The key difference here is that the execution of your script will block in the second example, until the file operation succeeded. 85 | -------------------------------------------------------------------------------- /documentation/0047-node-module-path/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'The Node path module' 3 | description: 'The path module of Node.js provides useful functions to interact with file paths' 4 | author: flaviocopes 5 | --- 6 | 7 | The `path` module provides a lot of very useful functionality to access and interact with the file system. 8 | 9 | There is no need to install it. Being part of the Node core, it can be used by simply requiring it: 10 | 11 | ```js 12 | const path = require('path') 13 | ``` 14 | 15 | This module provides `path.sep` which provides the path segment separator (`\` on Windows, and `/` on Linux / macOS), and `path.delimiter` which provides the path delimiter (`;` on Windows, and `:` on Linux / macOS). 16 | 17 | These are the `path` methods: 18 | 19 | 20 | 21 | - [`path.basename()`](#pathbasename) 22 | - [`path.dirname()`](#pathdirname) 23 | - [`path.extname()`](#pathextname) 24 | - [`path.isAbsolute()`](#pathisabsolute) 25 | - [`path.join()`](#pathjoin) 26 | - [`path.normalize()`](#pathnormalize) 27 | - [`path.parse()`](#pathparse) 28 | - [`path.relative()`](#pathrelative) 29 | - [`path.resolve()`](#pathresolve) 30 | 31 | 32 | 33 | ### `path.basename()` 34 | 35 | Return the last portion of a path. A second parameter can filter out the file extension: 36 | 37 | ```js 38 | require('path').basename('/test/something') //something 39 | require('path').basename('/test/something.txt') //something.txt 40 | require('path').basename('/test/something.txt', '.txt') //something 41 | ``` 42 | 43 | ### `path.dirname()` 44 | 45 | Return the directory part of a path: 46 | 47 | ```js 48 | require('path').dirname('/test/something') // /test 49 | require('path').dirname('/test/something/file.txt') // /test/something 50 | ``` 51 | 52 | ### `path.extname()` 53 | 54 | Return the extension part of a path 55 | 56 | ```js 57 | require('path').dirname('/test/something') // '' 58 | require('path').dirname('/test/something/file.txt') // '.txt' 59 | ``` 60 | 61 | ### `path.isAbsolute()` 62 | 63 | Returns true if it's an absolute path 64 | 65 | ```js 66 | require('path').isAbsolute('/test/something') // true 67 | require('path').isAbsolute('./test/something') // false 68 | ``` 69 | 70 | ### `path.join()` 71 | 72 | Joins two or more parts of a path: 73 | 74 | ```js 75 | const name = 'joe' 76 | require('path').join('/', 'users', name, 'notes.txt') //'/users/joe/notes.txt' 77 | ``` 78 | 79 | ### `path.normalize()` 80 | 81 | Tries to calculate the actual path when it contains relative specifiers like `.` or `..`, or double slashes: 82 | 83 | ```js 84 | require('path').normalize('/users/joe/..//test.txt') ///users/test.txt 85 | ``` 86 | 87 | ### `path.parse()` 88 | 89 | Parses a path to an object with the segments that compose it: 90 | 91 | - `root`: the root 92 | - `dir`: the folder path starting from the root 93 | - `base`: the file name + extension 94 | - `name`: the file name 95 | - `ext`: the file extension 96 | 97 | Example: 98 | 99 | ```js 100 | require('path').parse('/users/test.txt') 101 | ``` 102 | 103 | results in 104 | 105 | ```js 106 | { 107 | root: '/', 108 | dir: '/users', 109 | base: 'test.txt', 110 | ext: '.txt', 111 | name: 'test' 112 | } 113 | ``` 114 | 115 | ### `path.relative()` 116 | 117 | Accepts 2 paths as arguments. Returns the the relative path from the first path to the second, based on the current working directory. 118 | 119 | Example: 120 | 121 | ```js 122 | require('path').relative('/Users/joe', '/Users/joe/test.txt') //'test.txt' 123 | require('path').relative('/Users/joe', '/Users/joe/something/test.txt') //'something/test.txt' 124 | ``` 125 | 126 | ### `path.resolve()` 127 | 128 | You can get the absolute path calculation of a relative path using `path.resolve()`: 129 | 130 | ```js 131 | path.resolve('joe.txt') //'/Users/joe/joe.txt' if run from my home folder 132 | ``` 133 | 134 | By specifying a second parameter, `resolve` will use the first as a base for the second: 135 | 136 | ```js 137 | path.resolve('tmp', 'joe.txt') //'/Users/joe/tmp/joe.txt' if run from my home folder 138 | ``` 139 | 140 | If the first parameter starts with a slash, that means it's an absolute path: 141 | 142 | ```js 143 | path.resolve('/etc', 'joe.txt') //'/etc/joe.txt' 144 | ``` 145 | -------------------------------------------------------------------------------- /documentation/0048-node-module-os/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'The Node os module' 3 | description: 'The os module of Node.js provides useful functions to interact with underlying system' 4 | author: flaviocopes 5 | --- 6 | 7 | This module provides many functions that you can use to retrieve information from the underlying operating system and the computer the program runs on, and interact with it. 8 | 9 | ```js 10 | const os = require('os') 11 | ``` 12 | 13 | There are a few useful properties that tell us some key things related to handling files: 14 | 15 | `os.EOL` gives the line delimiter sequence. It's `\n` on Linux and macOS, and `\r\n` on Windows. 16 | 17 | `os.constants.signals` tells us all the constants related to handling process signals, like SIGHUP, SIGKILL and so on. 18 | 19 | `os.constants.errno` sets the constants for error reporting, like EADDRINUSE, EOVERFLOW and more. 20 | 21 | You can read them all on . 22 | 23 | Let's now see the main methods that `os` provides: 24 | 25 | 26 | 27 | - [`os.arch()`](#osarch) 28 | - [`os.cpus()`](#oscpus) 29 | - [`os.endianness()`](#osendianness) 30 | - [`os.freemem()`](#osfreemem) 31 | - [`os.homedir()`](#oshomedir) 32 | - [`os.hostname()`](#oshostname) 33 | - [`os.loadavg()`](#osloadavg) 34 | - [`os.networkInterfaces()`](#osnetworkinterfaces) 35 | - [`os.platform()`](#osplatform) 36 | - [`os.release()`](#osrelease) 37 | - [`os.tmpdir()`](#ostmpdir) 38 | - [`os.totalmem()`](#ostotalmem) 39 | - [`os.type()`](#ostype) 40 | - [`os.uptime()`](#osuptime) 41 | - [`os.userInfo()`](#osuserinfo) 42 | 43 | 44 | 45 | ## `os.arch()` 46 | 47 | Return the string that identifies the underlying architecture, like `arm`, `x64`, `arm64`. 48 | 49 | ## `os.cpus()` 50 | 51 | Return information on the CPUs available on your system. 52 | 53 | Example: 54 | 55 | ```js 56 | ;[ 57 | { 58 | model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz', 59 | speed: 2400, 60 | times: { 61 | user: 281685380, 62 | nice: 0, 63 | sys: 187986530, 64 | idle: 685833750, 65 | irq: 0 66 | } 67 | }, 68 | { 69 | model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz', 70 | speed: 2400, 71 | times: { 72 | user: 282348700, 73 | nice: 0, 74 | sys: 161800480, 75 | idle: 703509470, 76 | irq: 0 77 | } 78 | } 79 | ] 80 | ``` 81 | 82 | ## `os.endianness()` 83 | 84 | Return `BE` or `LE` depending if Node was compiled with [Big Endian or Little Endian](https://en.wikipedia.org/wiki/Endianness). 85 | 86 | ## `os.freemem()` 87 | 88 | Return the number of bytes that represent the free memory in the system. 89 | 90 | ## `os.homedir()` 91 | 92 | Return the path to the home directory of the current user. 93 | 94 | Example: 95 | 96 | ```js 97 | '/Users/joe' 98 | ``` 99 | 100 | ## `os.hostname()` 101 | 102 | Return the hostname. 103 | 104 | ## `os.loadavg()` 105 | 106 | Return the calculation made by the operating system on the load average. 107 | 108 | It only returns a meaningful value on Linux and macOS. 109 | 110 | Example: 111 | 112 | ```js 113 | ;[3.68798828125, 4.00244140625, 11.1181640625] 114 | ``` 115 | 116 | ## `os.networkInterfaces()` 117 | 118 | Returns the details of the network interfaces available on your system. 119 | 120 | Example: 121 | 122 | ```js 123 | { lo0: 124 | [ { address: '127.0.0.1', 125 | netmask: '255.0.0.0', 126 | family: 'IPv4', 127 | mac: 'fe:82:00:00:00:00', 128 | internal: true }, 129 | { address: '::1', 130 | netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', 131 | family: 'IPv6', 132 | mac: 'fe:82:00:00:00:00', 133 | scopeid: 0, 134 | internal: true }, 135 | { address: 'fe80::1', 136 | netmask: 'ffff:ffff:ffff:ffff::', 137 | family: 'IPv6', 138 | mac: 'fe:82:00:00:00:00', 139 | scopeid: 1, 140 | internal: true } ], 141 | en1: 142 | [ { address: 'fe82::9b:8282:d7e6:496e', 143 | netmask: 'ffff:ffff:ffff:ffff::', 144 | family: 'IPv6', 145 | mac: '06:00:00:02:0e:00', 146 | scopeid: 5, 147 | internal: false }, 148 | { address: '192.168.1.38', 149 | netmask: '255.255.255.0', 150 | family: 'IPv4', 151 | mac: '06:00:00:02:0e:00', 152 | internal: false } ], 153 | utun0: 154 | [ { address: 'fe80::2513:72bc:f405:61d0', 155 | netmask: 'ffff:ffff:ffff:ffff::', 156 | family: 'IPv6', 157 | mac: 'fe:80:00:20:00:00', 158 | scopeid: 8, 159 | internal: false } ] } 160 | ``` 161 | 162 | ## `os.platform()` 163 | 164 | Return the platform that Node was compiled for: 165 | 166 | - `darwin` 167 | - `freebsd` 168 | - `linux` 169 | - `openbsd` 170 | - `win32` 171 | - ...more 172 | 173 | ## `os.release()` 174 | 175 | Returns a string that identifies the operating system release number 176 | 177 | ## `os.tmpdir()` 178 | 179 | Returns the path to the assigned temp folder. 180 | 181 | ## `os.totalmem()` 182 | 183 | Returns the number of bytes that represent the total memory available in the system. 184 | 185 | ## `os.type()` 186 | 187 | Identifies the operating system: 188 | 189 | - `Linux` 190 | - `Darwin` on macOS 191 | - `Windows_NT` on Windows 192 | 193 | ## `os.uptime()` 194 | 195 | Returns the number of seconds the computer has been running since it was last rebooted. 196 | 197 | ## `os.userInfo()` 198 | -------------------------------------------------------------------------------- /documentation/0049-node-module-events/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'The Node events module' 3 | description: 'The events module of Node.js provides the EventEmitter class' 4 | author: flaviocopes 5 | --- 6 | 7 | The `events` module provides us the EventEmitter class, which is key to working with events in Node. 8 | 9 | ```js 10 | const EventEmitter = require('events') 11 | const door = new EventEmitter() 12 | ``` 13 | 14 | The event listener eats its own dog food and uses these events: 15 | 16 | - `newListener` when a listener is added 17 | - `removeListener` when a listener is removed 18 | 19 | Here's a detailed description of the most useful methods: 20 | 21 | 22 | 23 | - [`emitter.addListener()`](#emitteraddlistener) 24 | - [`emitter.emit()`](#emitteremit) 25 | - [`emitter.eventNames()`](#emittereventnames) 26 | - [`emitter.getMaxListeners()`](#emittergetmaxlisteners) 27 | - [`emitter.listenerCount()`](#emitterlistenercount) 28 | - [`emitter.listeners()`](#emitterlisteners) 29 | - [`emitter.off()`](#emitteroff) 30 | - [`emitter.on()`](#emitteron) 31 | - [`emitter.once()`](#emitteronce) 32 | - [`emitter.prependListener()`](#emitterprependlistener) 33 | - [`emitter.prependOnceListener()`](#emitterprependoncelistener) 34 | - [`emitter.removeAllListeners()`](#emitterremovealllisteners) 35 | - [`emitter.removeListener()`](#emitterremovelistener) 36 | - [`emitter.setMaxListeners()`](#emittersetmaxlisteners) 37 | 38 | 39 | 40 | ## `emitter.addListener()` 41 | 42 | Alias for `emitter.on()`. 43 | 44 | ## `emitter.emit()` 45 | 46 | Emits an event. It synchronously calls every event listener in the order they were registered. 47 | 48 | ## `emitter.eventNames()` 49 | 50 | Return an array of strings that represent the events registered on the current EventListener: 51 | 52 | ```js 53 | door.eventNames() 54 | ``` 55 | 56 | ## `emitter.getMaxListeners()` 57 | 58 | Get the maximum amount of listeners one can add to an EventListener object, which defaults to 10 but can be increased or lowered by using `setMaxListeners()` 59 | 60 | ```js 61 | door.getMaxListeners() 62 | ``` 63 | 64 | ## `emitter.listenerCount()` 65 | 66 | Get the count of listeners of the event passed as parameter: 67 | 68 | ```js 69 | door.listenerCount('open') 70 | ``` 71 | 72 | ## `emitter.listeners()` 73 | 74 | Gets an array of listeners of the event passed as parameter: 75 | 76 | ```js 77 | door.listeners('open') 78 | ``` 79 | 80 | ## `emitter.off()` 81 | 82 | Alias for `emitter.removeListener()` added in Node 10 83 | 84 | ## `emitter.on()` 85 | 86 | Adds a callback function that's called when an event is emitted. 87 | 88 | Usage: 89 | 90 | ```js 91 | door.on('open', () => { 92 | console.log('Door was opened') 93 | }) 94 | ``` 95 | 96 | ## `emitter.once()` 97 | 98 | Adds a callback function that's called when an event is emitted for the first time after registering this. This callback is only going to be called once, never again. 99 | 100 | ```js 101 | const EventEmitter = require('events') 102 | const ee = new EventEmitter() 103 | 104 | ee.once('my-event', () => { 105 | //call callback function once 106 | }) 107 | ``` 108 | 109 | ## `emitter.prependListener()` 110 | 111 | When you add a listener using `on` or `addListener`, it's added last in the queue of listeners, and called last. Using `prependListener` it's added, and called, before other listeners. 112 | 113 | ## `emitter.prependOnceListener()` 114 | 115 | When you add a listener using `once`, it's added last in the queue of listeners, and called last. Using `prependOnceListener` it's added, and called, before other listeners. 116 | 117 | ## `emitter.removeAllListeners()` 118 | 119 | Removes all listeners of an event emitter object listening to a specific event: 120 | 121 | ```js 122 | door.removeAllListeners('open') 123 | ``` 124 | 125 | ## `emitter.removeListener()` 126 | 127 | Remove a specific listener. You can do this by saving the callback function to a variable, when added, so you can reference it later: 128 | 129 | ```js 130 | const doSomething = () => {} 131 | door.on('open', doSomething) 132 | door.removeListener('open', doSomething) 133 | ``` 134 | 135 | ## `emitter.setMaxListeners()` 136 | 137 | Sets the maximum amount of listeners one can add to an EventListener object, which defaults to 10 but can be increased or lowered. 138 | 139 | ```js 140 | door.setMaxListeners(50) 141 | ``` 142 | -------------------------------------------------------------------------------- /documentation/0051-node-buffers/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Node Buffers 3 | description: 'Learn what Node buffers are, what they are used for, how to use them' 4 | author: flaviocopes 5 | --- 6 | 7 | ## What is a buffer? 8 | 9 | A buffer is an area of memory. JavaScript developers are not familiar with this concept, much less than C, C++ or Go developers (or any programmer that uses a system programming language), which interact with memory every day. 10 | 11 | It represents a fixed-size chunk of memory (can't be resized) allocated outside of the V8 JavaScript engine. 12 | 13 | You can think of a buffer like an array of integers, which each represent a byte of data. 14 | 15 | It is implemented by the Node [Buffer class](https://nodejs.org/api/buffer.html). 16 | 17 | ## Why do we need a buffer? 18 | 19 | Buffers were introduced to help developers deal with binary data, in an ecosystem that traditionally only dealt with strings rather than binaries. 20 | 21 | Buffers are deeply linked with streams. When a stream processor receives data faster than it can digest, it puts the data in a buffer. 22 | 23 | A simple visualization of a buffer is when you are watching a YouTube video and the red line goes beyond your visualization point: you are downloading data faster than you're viewing it, and your browser buffers it. 24 | 25 | ## How to create a buffer 26 | 27 | A buffer is created using the [`Buffer.from()`](https://nodejs.org/api/buffer.html#buffer_buffer_from_buffer_alloc_and_buffer_allocunsafe), [`Buffer.alloc()`](https://nodejs.org/api/buffer.html#buffer_class_method_buffer_alloc_size_fill_encoding), and [`Buffer.allocUnsafe()`](https://nodejs.org/api/buffer.html#buffer_class_method_buffer_allocunsafe_size) methods. 28 | 29 | ```js 30 | const buf = Buffer.from('Hey!') 31 | ``` 32 | You can optionally pass the encoding in the second parameter (defaults to UTF-8). 33 | 34 | You can also initialize a buffer with a size. This creates a 1KB buffer: 35 | 36 | ```js 37 | const buf = Buffer.alloc(1024) 38 | ``` 39 | 40 | ## Using a buffer 41 | 42 | ### Access the content of a buffer 43 | 44 | A buffer, being an array of bytes, can be accessed like an array: 45 | 46 | ```js 47 | const buf = Buffer.from('Hey!') 48 | console.log(buf[0]) //72 49 | console.log(buf[1]) //101 50 | console.log(buf[2]) //121 51 | ``` 52 | 53 | Those numbers are the Unicode Code that identifies the character in the buffer position (H => 72, e => 101, y => 121) 54 | 55 | You can print the full content of the buffer using the `toString()` method: 56 | 57 | ```js 58 | console.log(buf.toString()) 59 | ``` 60 | 61 | > Notice that if you initialize a buffer with a number that sets its size, you'll get access to pre-initialized memory that will contain random data, not an empty buffer! 62 | 63 | ### Get the length of a buffer 64 | 65 | Use the `length` property: 66 | 67 | ```js 68 | const buf = Buffer.from('Hey!') 69 | console.log(buf.length) 70 | ``` 71 | 72 | ### Iterate over the contents of a buffer 73 | 74 | ```js 75 | const buf = Buffer.from('Hey!') 76 | for (const item of buf) { 77 | console.log(item) //72 101 121 33 78 | } 79 | ``` 80 | 81 | ### Changing the content of a buffer 82 | 83 | You can write to a buffer a whole string of data by using the `write()` method: 84 | 85 | ```js 86 | const buf = Buffer.alloc(4) 87 | buf.write('Hey!') 88 | ``` 89 | 90 | Just like you can access a buffer with an array syntax, you can also set the contents of the buffer in the same way: 91 | 92 | ```js 93 | const buf = Buffer.from('Hey!') 94 | buf[1] = 111 //o 95 | console.log(buf.toString()) //Hoy! 96 | ``` 97 | 98 | ### Copy a buffer 99 | 100 | Copying a buffer is possible using the `copy()` method: 101 | 102 | ```js 103 | const buf = Buffer.from('Hey!') 104 | let bufcopy = Buffer.alloc(4) //allocate 4 bytes 105 | buf.copy(bufcopy) 106 | ``` 107 | 108 | By default you copy the whole buffer. 3 more parameters let you define the starting position, the ending position, and the new buffer length: 109 | 110 | ```js 111 | const buf = Buffer.from('Hey!') 112 | let bufcopy = Buffer.alloc(2) //allocate 2 bytes 113 | buf.copy(bufcopy, 0, 2, 2) 114 | bufcopy.toString() //'He' 115 | ``` 116 | 117 | ### Slice a buffer 118 | 119 | If you want to create a partial visualization of a buffer, you can create a slice. A slice is not a copy: the original buffer is still the source of truth. If that changes, your slice changes. 120 | 121 | Use the `slice()` method to create it. The first parameter is the starting position, and you can specify an optional second parameter with the end position: 122 | 123 | ```js 124 | const buf = Buffer.from('Hey!') 125 | buf.slice(0).toString() //Hey! 126 | const slice = buf.slice(0, 2) 127 | console.log(slice.toString()) //He 128 | buf[1] = 111 //o 129 | console.log(slice.toString()) 130 | ``` 131 | -------------------------------------------------------------------------------- /documentation/0053-node-difference-dev-prod/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Node, the difference between development and production 3 | description: 'Learn how to set up different configurations for production and development environments' 4 | author: flaviocopes 5 | --- 6 | 7 | You can have different configurations for production and development environments. 8 | 9 | Node assumes it's always running in a development environment. 10 | You can signal Node.js that you are running in production by setting the `NODE_ENV=production` environment variable. 11 | 12 | This is usually done by executing the command 13 | 14 | ```sh 15 | export NODE_ENV=production 16 | ``` 17 | 18 | in the shell, but it's better to put it in your shell configuration file (e.g. `.bash_profile` with the Bash shell) because otherwise the setting does not persist in case of a system restart. 19 | 20 | You can also apply the environment variable by prepending it to your application initialization command: 21 | 22 | ```sh 23 | NODE_ENV=production node app.js 24 | ``` 25 | 26 | This environment variable is a convention that is widely used in external libraries as well. 27 | 28 | Setting the environment to `production` generally ensures that 29 | 30 | - logging is kept to a minimum, essential level 31 | - more caching levels take place to optimize performance 32 | 33 | For example Pug, the templating library used by Express, compiles in debug mode if `NODE_ENV` is not set to `production`. Express views are compiled in every request in development mode, while in production they are cached. There are many more examples. 34 | 35 | Express provides configuration hooks specific to the environment, which are automatically called based on the NODE_ENV variable value: 36 | 37 | ```js 38 | app.configure('development', () => { 39 | //... 40 | }) 41 | app.configure('production', () => { 42 | //... 43 | }) 44 | app.configure('production', 'staging', () => { 45 | //... 46 | }) 47 | ``` 48 | 49 | For example you can use this to set different error handlers for different mode: 50 | 51 | ```js 52 | app.configure('development', () => { 53 | app.use(express.errorHandler({ dumpExceptions: true, showStack: true })) 54 | }) 55 | 56 | app.configure('production', () => { 57 | app.use(express.errorHandler()) 58 | }) 59 | ``` 60 | -------------------------------------------------------------------------------- /documentation/0054-node-exceptions/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Error handling in Node.js 3 | description: 'How to handle errors during the execution of a Node.js application' 4 | author: flaviocopes 5 | --- 6 | 7 | Errors in Node.js are handled through exceptions. 8 | 9 | ## Creating exceptions 10 | 11 | An exception is created using the `throw` keyword: 12 | 13 | ```js 14 | throw value 15 | ``` 16 | 17 | As soon as JavaScript executes this line, the normal program flow is halted and the control is held back to the nearest **exception handler**. 18 | 19 | Usually in client-side code `value` can be any JavaScript value including a string, a number or an object. 20 | 21 | In Node.js, we don't throw strings, we just throw Error objects. 22 | 23 | ## Error objects 24 | 25 | An error object is an object that is either an instance of the Error object, or extends the Error class, provided in the [Error core module](https://nodejs.org/api/errors.html): 26 | 27 | ```js 28 | throw new Error('Ran out of coffee') 29 | ``` 30 | 31 | or 32 | 33 | ```js 34 | class NotEnoughCoffeeError extends Error { 35 | //... 36 | } 37 | throw new NotEnoughCoffeeError() 38 | ``` 39 | 40 | ## Handling exceptions 41 | 42 | An exception handler is a `try`/`catch` statement. 43 | 44 | Any exception raised in the lines of code included in the `try` block is handled in the corresponding `catch` block: 45 | 46 | ```js 47 | try { 48 | //lines of code 49 | } catch (e) {} 50 | ``` 51 | 52 | `e` in this example is the exception value. 53 | 54 | You can add multiple handlers, that can catch different kinds of errors. 55 | 56 | ## Catching uncaught exceptions 57 | 58 | If an uncaught exception gets thrown during the execution of your program, your program will crash. 59 | 60 | To solve this, you listen for the `uncaughtException` event on the `process` object: 61 | 62 | ```js 63 | process.on('uncaughtException', err => { 64 | console.error('There was an uncaught error', err) 65 | process.exit(1) //mandatory (as per the Node docs) 66 | }) 67 | ``` 68 | 69 | You don't need to import the `process` core module for this, as it's automatically injected. 70 | 71 | ## Exceptions with promises 72 | 73 | Using promises you can chain different operations, and handle errors at the end: 74 | 75 | ```js 76 | doSomething1() 77 | .then(doSomething2()) 78 | .then(doSomething3()) 79 | .catch(err => console.error(err)) 80 | ``` 81 | 82 | How do you know where the error occurred? You don't really know, but you can handle errors in each of the functions you call (`doSomethingX`), and inside the error handler throw a new error, that's going to call the outside `catch` handler: 83 | 84 | ```js 85 | const doSomething1 = () => { 86 | //... 87 | try { 88 | //... 89 | } catch (err) { 90 | //... handle it locally 91 | throw new Error(err.message) 92 | } 93 | //... 94 | } 95 | ``` 96 | 97 | To be able to handle errors locally without handling them in the function we call, we can break the chain you can create a function in each `then()` and process the exception: 98 | 99 | ```js 100 | doSomething1 101 | .then((() => { 102 | return doSomething2().catch(err => { 103 | //handle error 104 | throw err //break the chain! 105 | }) 106 | }) 107 | .then((() => { 108 | return doSomething2().catch(err => { 109 | //handle error 110 | throw err //break the chain! 111 | }) 112 | }) 113 | .catch(err => console.error(err)) 114 | ``` 115 | 116 | ## Error handling with async/await 117 | 118 | Using async/await, you still need to catch errors, and you do it this way: 119 | 120 | ```js 121 | async function someFunction() { 122 | try { 123 | await someOtherFunction() 124 | } catch (err) { 125 | console.error(err.message) 126 | } 127 | } 128 | ``` 129 | -------------------------------------------------------------------------------- /documentation/0055-node-inspect-object/console-log-browser-expanded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0055-node-inspect-object/console-log-browser-expanded.png -------------------------------------------------------------------------------- /documentation/0055-node-inspect-object/console-log-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodejs/website-redesign/1b840fc7c37ed7c9de69c2e5560bf9c086a72868/documentation/0055-node-inspect-object/console-log-browser.png -------------------------------------------------------------------------------- /documentation/0055-node-inspect-object/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to log an object in Node 3 | description: 'Logging objects in Node.js' 4 | author: flaviocopes 5 | --- 6 | 7 | When you type `console.log()` into a JavaScript program that runs in the browser, that is going to create a nice entry in the Browser Console: 8 | 9 | ![](console-log-browser.png) 10 | 11 | Once you click the arrow, the log is expanded, and you can clearly see the object properties: 12 | 13 | ![](console-log-browser-expanded.png) 14 | 15 | In Node, the same happens. 16 | 17 | We don’t have such luxury when we log something to the console, because that’s going to output the object to the shell if you run the Node program manually, or to the log file. You get a string representation of the object. 18 | 19 | Now, all is fine until a certain level of nesting. After two levels of nesting, Node gives up and prints `[Object]` as a placeholder: 20 | 21 | ``` 22 | const obj = { 23 | name: 'joe', 24 | age: 35, 25 | person1: { 26 | name: 'Tony', 27 | age: 50, 28 | person2: { 29 | name: 'Albert', 30 | age: 21, 31 | person3: { 32 | name: 'Peter', 33 | age: 23 34 | } 35 | } 36 | } 37 | } 38 | console.log(obj) 39 | 40 | 41 | { 42 | name: 'joe', 43 | age: 35, 44 | person1: { 45 | name: 'Tony', 46 | age: 50, 47 | person2: { 48 | name: 'Albert', 49 | age: 21, 50 | person3: [Object] 51 | } 52 | } 53 | } 54 | ``` 55 | 56 | How can you print the whole object? 57 | 58 | The best way to do so, while preserving the pretty print, is to use 59 | 60 | ```js 61 | console.log(JSON.stringify(obj, null, 2)) 62 | ``` 63 | 64 | where `2` is the number of spaces to use for indentation. 65 | 66 | Another option is to use 67 | 68 | ```js 69 | require('util').inspect.defaultOptions.depth = null 70 | console.log(obj) 71 | ``` 72 | 73 | but the problem is that the nested objects after level 2 are now flattened, and this might be a problem with complex objects. 74 | -------------------------------------------------------------------------------- /documentation/README.md: -------------------------------------------------------------------------------- 1 | # Documentation RFCs (Request for Comments) 2 | 3 | While the Website Redesign working group continues to iterate on site design and content structure, we will use an RFC process to accept and evaluate Node.js documentation contributions in this repo. Once the new site architecture and documentation ingestion flow is finalized, all docs content will be migrated to its final location and this process updated accordingly. 4 | 5 | ## When you need to follow this process 6 | 7 | With the working group iterating on design and content structure, this process is our way of making sure all content gets good feedback and, with approval, eventually finds its way to the right place in the documentation. 8 | 9 | You need to follow this process if you intend to make a "substantial" addition or change to the proposed Node.js getting started guides in this repo. What constitutes a "substantial" change evolves based on community norms. Some changes do not require an RFC. These may include reasonably sized re-phasing, reorganizing, or refactoring an existing documentation page. 10 | 11 | If you submit a pull request to implement a significant change to the documentation without going through the RFC process, it may be closed with a polite request to submit an RFC first! 12 | 13 | ## To begin drafting a documentation page: 14 | 15 | 1. Fork the [nodejs/website-redesign repo](https://github.com/nodejs/website-redesign) so that you have your own copy of the repository that you have push access to. 16 | 2. Create a new folder for your documentation to live in by copying the given template folder found at `documentation/0000-template` to a new folder `documentation/0000-my-article-name` (replacing 'my-article-name' with a descriptive name of what your article is about. Leave the 0000 as it is, since we don't need to assign your article a page number yet). 17 | 3. You should now have a new folder that contains an article.md file that will serve as the template that you will use for your documentation. Edit this article.md file and begin writing out your article. Put care into the details! Please review the proposed [Node.js Voice and Tone Guidelines](https://github.com/nodejs/website-redesign/blob/master/style-guide/0001-voice-and-tone.md) before you begin writing. 18 | 4. When you are ready to get some feedback on your article, submit a pull request back to the main nodejs/website-redesign repository. As a pull request, the draft will receive feedback from the larger community, and the author should be prepared to revise it in response. 19 | 5. Build consensus on your article by integrating feedback from the community. 20 | 6. Eventually, the Website Redesign Working Group will decide in one of their bi-weekly meetings whether the RFC is a candidate for inclusion on the Node.js website. 21 | 22 | RFCs that are candidates for inclusion on the Node.js website will enter a "final comment period" lasting 7 days. The beginning of this period will be signaled with a comment and tag on the RFC's pull request. The RFC can be modified based upon feedback from the community. Significant modifications may trigger a new final comment period. At the close of this review period, the RFC may be: 23 | 24 | * accepted at the close of its final comment period. A working group member will merge the RFC's associated pull request, at which point the RFC will become 'active', or; 25 | 26 | * rejected by the Website Redesign working group after public discussion has settled and comments have been made summarizing the rationale for rejection. A member of the working group should then close the RFC's associated pull request. 27 | -------------------------------------------------------------------------------- /meetings/2018-02-01.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Initiative Meeting 2018-02-01 2 | 3 | ## Present 4 | - @oe 5 | - @bnb 6 | - @chowdhurian 7 | - @fhemberger 8 | - @amiller-gh 9 | - @maddhruv 10 | - @timothyis 11 | - @franciscop 12 | - @mrhinkle 13 | 14 | ## Notes 15 | 16 | - Prioritizing agenda 17 | 18 | ### General objectives, strategy going forward 19 | 20 | - Olivia, Tierney: We should ensure that goals are long-term 21 | - Adam: Rediscussing the points listed in https://github.com/nodejs/nodejs.org/issues/1534 22 | - Adam: Site Structure, Design, Implementation 23 | - Adam: In that order 24 | - Olivia: Previous discussions have been too implementation-focused 25 | 26 | - Olivia: before we get down the agenda, what cadence do we want the meetings to be on 27 | - General agreement: every 2 weeks 28 | 29 | ### Overall site structure 30 | 31 | - See also https://github.com/nodejs/nodejs.org/issues/1534 (Assess current site structure, see what's needed and what's not). 32 | 33 | - Frederic: History of website. There never was a well defined content structure, it was made as needed. 34 | - Jeremiah: brief notes on iojs.org’s design 35 | - Adam: sounds like now’s a good time to do something more design focused 36 | - Tierney: an overview of some obstacles on the current website 37 | - Olivia: Make it easier to add information in a more structured manner. 38 | - Adam: Also a good opportunity to have a design-focused process for contribution review 39 | - Adam: Process for PR to add content to site, would help the different stakeholders who add content to site. 40 | - Olivia: Suggestion to start. What do we have now, a sort of site map. Then go from there. 41 | - Frederic: volunteers to write up a site map of the existing site (link) 42 | - Tierney, Jeremiah: discussion of how the node api docs are maintained somewhat separate. 43 | - Adam: Overview of his blog post write up which compares to other “competeting” websites in some detail: https://medium.com/the-node-js-collection/redesigning-nodejs-part-1-fac08a0e015a 44 | - Fransisco: what are the main goals of the current website? 45 | - Tierney: Primary uses of site to date: Downloads, information, Documentation, Getting involved. 46 | 47 | ### Addressing content held in separate repositories 48 | 49 | - Olivia: How should we address documents in separate repositories? 50 | - Frederic: I want to see the Code of Conduct, governance docs, etc, directly. Should be part of the website. 51 | - Adam: I’d love to see some “Learn” page, a normal-language guided tour. Something more comprehensive and ergonomic. 52 | - Adam: We may not need to write this content as it may already exist and we may be able to get it contributed back. 53 | - Frederic: The getting started guides are currently at https://nodejs.org/en/docs/guides/getting-started-guide/, needs to be surfaced better. As does the introduction https://nodejs.org/en/about/. 54 | - Adam: The site should feel more cohesive. 55 | - Timothy: I don’t really agree - have seen other examples where the docs and main site work for different purposes. 56 | - Adam: Some things should probably look the same as the home page, e.g. the ‘getting started’. 57 | - Adam: So long as implementation doesn’t impact design 58 | 59 | ### Syncing with the Node.js Foundation website 60 | 61 | - Frederic: Let’s also think about the foundation website: They have a wordpress setup right now, but at the moment the foundation website looks totally different. (There could be a technical solution to keep the WP theme with the website layout in sync.) 62 | - Olivia: We might need to figure that out as we go, we’ll need to stay in contact with the people who manage the foundation website. 63 | - Tierney: We should avoid duplicating too much content between Foundation and Node.js website. 64 | - Adam: Let’s invite the foundation site maintainers to these meetings. 65 | - Adam: As for unifying theming and branding - I don’t think it is unreasonable to come from the design with a full process for theming Node.js branded websites. 66 | 67 | ### Decision structure (consensus, etc.) 68 | 69 | - There is a Foundation marketing committee. Check with Greg (gwallace@linuxfoundation.org) 70 | - Tierney: I sit on that committee as part of my job, and it is a pretty open group. 71 | 72 | - Discussion of existing consensus-seeking model, seems acceptable (lazy consensus). 73 | 74 | ### Missing requirements 75 | 76 | - Adam: documentation versions switcher (external) 77 | - Adam: Better release structure overview (LTS schedule, etc) 78 | - Adam: Robust community page 79 | - Adam: Present the blog better 80 | - Olivia: Is there a way we can consolidate the medium blog into the website when the time comes? 81 | - Adam: I think there needs to be a strong distinction between community content and official (changelog, etc) content. I think these should stay separate. 82 | - Split news into blog and release notes (and remove them from the regular blog)? 83 | 84 | - Some other related discussion 85 | 86 | - Francisco: Hard to search the docs. 87 | - Tierney: We should probably try to get a little higher level than the content in this planning. 88 | - Timothy: We probably need a collection of higher-level content needs, what general site functionality is required. 89 | 90 | ### Previous attempts at redesigning the website 91 | 92 | - Frederic: Two previous attempts 93 | - Frederic: One was from Leo, but had no content/structure discussion, just design/mockups. 94 | - Frederic: The other time was something from the foundation, but never came to anything. 95 | - Frederic: Was poor communication with the foundation there. 96 | - Olivia: Neither really came from the community itself… 97 | - Tierney: Both were a single point of failure, didn’t have enough time and ultimately dropped it. 98 | - Timothy: It is clear we need to remember this is a really big challenge, we need to break it down into manageable chunks. 99 | - Olivia: We could actually hire a designer with foundation funds if necessary... 100 | - Mark: (Some discussion on how hiring someone would work between the foundation.) 101 | 102 | - Some discussion of previous design competitions e.g. the logo (mixed results regarding brand experience, overall design, etc.) 103 | 104 | - Olivia: Any other questions before we end? 105 | - Adam: If we have the ability to hire, are we able to do lower-level brand design e.g. the logo if necessary/desired? 106 | 107 | - Francisco: Should we estimate a timeline? Is getting a designer even possible this year? 108 | - Mark: (Some clarification of funds allocation.) 109 | - Olivia: As to general timeline… good question. Hard to pinpoint down at this point. 110 | - Jeremiah: No less than 6 months. 111 | -------------------------------------------------------------------------------- /meetings/2018-02-15.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Initiative Meeting 2018-02-15 2 | 3 | ## Present 4 | * Olivia Hugger 5 | * Tierney Cyren 6 | * Adam Miller 7 | * Manil Chowdhury 8 | * Frederic Hemberger 9 | * Jeremiah Senkpiel 10 | * Emily Mendez 11 | 12 | ## Notes 13 | Order in the agenda will be rearranged to prioritize issues 14 | 15 | ### Overall site structure #4 16 | 17 | * group discussed overall structure proposed by Adam, no objections were raised 18 | * wireframe the suggestions and share to github 19 | * TODO: Set up balsamiq and get a GDoc configured with it 20 | https://chrome.google.com/webstore/detail/balsamiq-wireframes-for-d/jmebhflpaooegildgjfecegknjahhfki?hl=en 21 | * Sub-sites of nodejs.org 22 | 23 | 24 | ### Getting started section #9 25 | 26 | * Nodejitsu handed over their Knowledge Base, it’s not linked on the website yet. 27 | * Needs to be reviewed, probably outdated but could be a good starting point. 28 | * This will be a longer-term, content-heavy effort that will be a WIP well beyond the redesign launch 29 | * Reach out to NodeSchool, regarding Getting Started content 30 | * Should include multiple approaches to getting started, i.e. web app, FaaS, CLI, etc. 31 | * TODO: Investigate how frameworks and languages implement interactive Getting Started experiences 32 | 33 | ### Updating Node.js messaging #242 (in CommComm) 34 | * Also discussed in nodejs.org/#1534: 35 | Examples: 36 | - http://styleguide.mailchimp.com
 37 | - http://voiceandtone.com 38 | * messaging is old and may have been outgrown 39 | * Existing content in Evangelism repo: Social Media Style Guide 40 | * Must make sure to collaborate with the Foundation to make sure of buy in 41 | 42 | ### Components library #5 43 | * Paused till future when architecture etc has been determined 44 | 45 | ### Timeline 46 | 47 | * Timeboxing can be demotivating 48 | * Suggested approach: At the beginning of each section (eg. Architecture), estimate how long it’ll take, surface in the meeting, update as needed 49 | 50 | ## Timeline Review: 51 | * 2 week deliverables (architecture phase ongoing): real content for Learning, detailed wireframe 52 | 53 | -------------------------------------------------------------------------------- /meetings/2018-03-01.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Initiative Meeting 2018-03-01 2 | 3 | ## Present 4 | - Darcy (@darcyclarke) 5 | - Olivia (@oe) 6 | - Francisco (@franciscop) 7 | - Adam Miller (@amiller-gh) 8 | - Tierney (@bnb) 9 | - Dhruv Jain (@maddhruv) 10 | - Manil (@chowdhurian) 11 | 12 | ## Notes 13 | Order in the agenda will be rearranged to prioritize issues 14 | 15 | ### Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 16 | Context: We left the last meeting with an action item to have wireframes for discussion by next discussion. Adam makes first pass and put it together. Much activity, we notice visuals helps increase engagement. There are a lot of outstanding questions. Intent is broad strokes for site flow. 17 | * Suggest prioritizing content. 18 | * The largest point of discussion was how the download button works in the home page. Maybe set up three options and ask for feedback. 19 | * Analytics: There are analytics for the nodejs org site. We don’t have access but we can request from Zibby Keaton. Caution against putting too much stock in that instead of doing enough user exploration. 20 | * Goals: Clear navigation hierarchy that surfaces everything. Restructuring the current website that has several years of tacked on additions. 21 | * Content: Would want more content for this on Getting Started. 22 | * TODO: Open up a user personas issue. 23 | 24 | 25 | ### Voice and Tone Guidelines [#13](https://github.com/nodejs/website-redesign/issues/13) 26 | * Prepare the document as if it could be used beyond the scope but the scope is unchanged. 27 | * TODO: Make clear in the doc, the use of humour and recommended voice for that. 28 | * Different people may have different types of humour and mixing them together could have unexpected effects. 29 | * Humour varies across cultures. We need to be mindful while maintaining a sense of humour. 30 | * Bring up with i18n working group, to see what happens if humour doesn’t translate and what the fallback is. 31 | * TODO: ping the i18n WG in the issue. 32 | * Creating the user personas, who comes to conferences, who comes to website, to see what kind of humour would be acceptable. It could be very off-putting if the audience doesn’t feel the same kind of humour as the company. Err on the side of being serious. 33 | * TODO: add humour to user personas issues. 34 | 35 | ### Tech Exploration for In-Browser Node Playground [#12](https://github.com/nodejs/website-redesign/issues/12) (related to, but not the same as, [#9](https://github.com/nodejs/website-redesign/issues/9)) 36 | Context: Console/editor with which to test the capabilities of node. 37 | * It could be useful on the homepage and the learning page 38 | * Glitch has a heavy focus on the Nodejs community and bringing new people into Node 39 | * Runkit has a few options to dynamically create the embedded script 40 | * TODO: explore the suggested options to see which fits the needs 41 | * Runkit: you don’t see package files which is arguably better for tutorials 42 | * The objective: We need to identify the feature set that best satisfies the needs of the code playground. 43 | 44 | 45 | ### Getting started section [#9](https://github.com/nodejs/website-redesign/issues/9) 46 | * Past TODO: Investigate how frameworks and languages implement interactive Getting Started experiences 47 | * The purpose: onboard people on getting running from scratch. We should add more detailed getting started docs. 48 | * Suggest a learning path doc. A suggested path, where if completed someone will know how to use nodejs and start on more custom things. 49 | * Is there a way within Getting Started to tie into NodeSchool and other community initiatives? For this, the workshoppers need to be updated (some are Node 4). These would need an official maintainer to ensure they’re up to date. 50 | * TODO: open a new issue to explore connecting to NodeSchool on Getting Started 51 | 52 | 53 | ### Updating Node.js messaging [#242](https://github.com/nodejs/community-committee/issues/242) (in CommComm) 54 | * It’s good for a technical person coming to Nodejs for the first time, but not for other people. Focus on this for content building rather than in the content definition space. 55 | * Open an issue for this in /admin because it’s a huge org wide scope. 56 | 57 | 58 | ### Overall site structure [#4](https://github.com/nodejs/website-redesign/issues/4) 59 | * past TODO: Set up balsamiq and get a GDoc configured with it 60 | 61 | 62 | ### Notes 63 | * Can start iterating on parts of the site where significant discussion has been had. 64 | * TODO: Make doodle for new meeting time. Until then, meeting time remains the same 65 | 66 | 67 | ## Timeline Review: 68 | * Suggested approach from earlier meeting: At the beginning of each section (eg. Architecture), estimate how long it’ll take, surface in the meeting, update as needed 69 | * 2018-02-15: 2 week deliverables (architecture phase ongoing): real content for Learning, detailed wireframe 70 | 71 | 72 | -------------------------------------------------------------------------------- /meetings/2018-03-15.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-03-15 2 | 3 | ## Present 4 | - Manil Chowdhury (@chowdhurian) 5 | - Darcy Clarke (@darcyclarke) 6 | - Tierney Cyren (@bnb) 7 | - Adam Miller (@amiller-gh) 8 | 9 | ## Agenda 10 | 11 | ### Notes 12 | 13 | #### Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 14 | * Hot button issue needs input from the release team 15 | * Do we want the package manager included? We have traffic numbers for the package manager page. Bringing that and showing its popularity to the release team may further the cause. 16 | 17 | #### Getting started with node [#9](https://github.com/nodejs/website-redesign/issues/9) 18 | * Some of this could actually go into Learn section 19 | * For the embedded runtime: What do we want? 20 | * We want people to be able to jump in and use it without having the install dependencies 21 | * We want to build up from JS knowledge and take users into using Node 22 | * Do we want to also guide through Express or just explain Node core? The power of Node is the ecosystem and we should strike a balance. Take a look at how NodeSchool separates Core workshoppers from Electives. 23 | 24 | TODO Tierney: Organize another meeting between NodeSchool and the Website Redesign Initiative 25 | 26 | #### Content structure [#4](https://github.com/nodejs/website-redesign/issues/4) 27 | 28 | ## Q&A, Other 29 | 30 | #### 31 | 32 | #### IA Document Summary 33 | - Wireframes 34 | - Content Graph 35 | - Analytics 36 | - Research / Competitive Analysis 37 | - Personas 38 | - Goals 39 | - Moodboards / Styleguides 40 | 41 | #### Repl Discovery Work 42 | - Requirements / Support: 43 | - Versions 44 | - Embeddable 45 | - Package resolution 46 | - Minimal branding 47 | - Maintained 48 | - Cost 49 | - Stdout / Console 50 | 51 | ## Upcoming Meetings 52 | 53 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 54 | 55 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 56 | -------------------------------------------------------------------------------- /meetings/2018-03-29.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-03-29 2 | 3 | ## Present 4 | * Tierney Cyren (@bnb) 5 | * Olivia Hugger (@oe) 6 | * Dhruv Jain (@maddhruv) 7 | * Adam Miller (@amiller-gh) 8 | * Manil (@chowdhurian) 9 | 10 | ## Agenda 11 | 12 | ### Notes 13 | 14 | #### Coordinating "Getting Started" content with NodeSchool content [#18](https://github.com/nodejs/website-redesign/issues/18) 15 | * one person responded, but we may not get the engagement that we’re looking 16 | * suggest we need to re-prioritize this task 17 | * looking for a meeting to see if we can get the interactive tooling into our getting started 18 | * there was also an understanding that we would get content from them 19 | * depending on the amount of engagement we can start with content and go from there 20 | * maybe instead of going to Nodeschool, go straight to the Learnyounode repo maintainers 21 | * https://github.com/workshopper/learnyounode 22 | * reiterate having a dedicated meeting with open invitation. “We’re using what you have as a foundation. We’d like to have you involved.” 23 | * TODO: Tierney creating an issue for dedicated meeting 24 | 25 | #### Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 26 | * There’s been additional feedback from the TSC on the path we should go down for Downloads 27 | * keep pressing the issue of package manager 28 | * TODO: Tierney and Adam will work to meet with the TSC on this discussion 29 | * Feedback around the releases section in the downloads page: 30 | * The full releases section probably isn’t useful as a source for downloads, since most downloads of older versions of Node.js are automated deployments and not direct downloads from the site 31 | * The metadata portion of it is interesting and useful, and worth having. Even having it in a truncated but expandable way for each release line would be helpful and a nice addition to the site. 32 | 33 | #### Tech Exploration for In-Browser Node Playground [#12](https://github.com/nodejs/website-redesign/issues/12) 34 | * bring back next meeting 35 | * Getting Started will inform what this look like 36 | * to be included in the meeting around Getting Started content and material 37 | * once we have some idea of content and material, reach out to Jenn Schiffer and Runkit, see if it would work on their platform. They would have good feedback 38 | * TODO: invite Jenn to the Getting Started meeting 39 | 40 | #### Voice and tone guidelines [#13](https://github.com/nodejs/website-redesign/issues/13) 41 | * some new content added to PR, re: humour in voice 42 | * waiting on more feedback 43 | * TODO: review to come 44 | 45 | #### Content Structure [#4](https://github.com/nodejs/website-redesign/issues/14) 46 | * suggest that we have a Branding page in the Community section, in a similar vein to what Webpack does: https://webpack.js.org/branding/ 47 | * we need consistency to help inform colour palettes, and the correct spelling of Node.js, assets; for the benefit of anyone working in design and community 48 | 49 | ## Announcements 50 | 51 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 52 | 53 | ## Q&A, Other 54 | * TODO: Manil to add website-redesign initiative talking points for Collab Summit 55 | 56 | ## Upcoming Meetings 57 | 58 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 59 | 60 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 61 | 62 | -------------------------------------------------------------------------------- /meetings/2018-04-12.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-04-12 2 | 3 | ## Links 4 | 5 | * **Recording**: https://www.youtube.com/watch?v=YJaBlwCfg1o 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/30 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/148YR77GBZf10B45zFR0BTppbrCT3IghE40I3dxOT1kk/edit 8 | 9 | ## Present 10 | Manil Chowdhury (@chowdhurian) 11 | Tierney Cyren (@bnb) 12 | Adam Miller (@amiller-gh) 13 | Francisco Tomalsky (@tomalsky) 14 | Abraham Agiri Jnr. (@codeekage) 15 | 16 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 17 | 18 | ## Agenda 19 | 20 | * Coordinating "Getting Started" content with NodeSchool content [#18](https://github.com/nodejs/website-redesign/issues/18) 21 | * Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 22 | * Tech Exploration for In-Browser Node Playground [#12](https://github.com/nodejs/website-redesign/issues/12) 23 | 24 | ## Announcements 25 | 26 | @oe is stepping back from managing the @nodejs/website-redesign initiative. @chowdhurian and @amiller-gh are stepping up as co-champions for the initiative. 27 | 28 | Welcome @codeekage to the team! Happy to have you! 29 | 30 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 31 | 32 | ### nodejs/website-redesign 33 | 34 | #### Coordinating "Getting Started" content with NodeSchool content [#18](https://github.com/nodejs/website-redesign/issues/18) 35 | * shouldn’t let getting started block us. 36 | * We should start to transition to active content development and high-fidelity mockups – can happen in tandem. 37 | * Should move on the getting started breakout meeting 38 | 39 | #### Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 40 | * Adam: Made updates to reflect feedback on download and releases flow. Will be live soon. 41 | * The homepage needs an iteration for content. For homepage, the content will inform the layout so we’ll need to do that first. 42 | * Homepage will need a space for events that the Foundation can push to, and security notifications 43 | * We need tighter feedback loop (such as a dedicated channel in Node Slackers or Twitter DMs) between design iterations and users 44 | 45 | #### Tech Exploration for In-Browser Node Playground [#12](https://github.com/nodejs/website-redesign/issues/12) 46 | 47 | * See [RunKit demo](http://nodejs-org-runkit-demo.com/) 48 | * Idea from RunKit: Active Nightly Demos? 49 | * Docs run behind nightlies, dedicated “hot features” page? 50 | * Lock RunKit Node version down to docs version 51 | 52 | ## Action Items 53 | 54 | * TODO: Manil to split out the current team members by interest in IA, Design, Code. 55 | * TODO: Adam to send out Dribble for breakout meeting. 56 | * TODO: Adam/Tierney to make a list of items we want on Getting Started. 57 | * TODO: Adam to create Node Slackers #website-redesign channel. 58 | * TODO: Adam to submit a Node.js extended colour palette for review. 59 | 60 | ## Q&A, Other 61 | 62 | ## Upcoming Meetings 63 | 64 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 65 | 66 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 67 | 68 | -------------------------------------------------------------------------------- /meetings/2018-04-26.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-04-26 2 | 3 | ## Links 4 | 5 | * **Recording**: https://www.youtube.com/watch?v=M2pLEkJuCEk 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/38 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1qj9JJRzbO-cCbwG5-NZeQF5A3avSe1G-NfkOC7BLplY/edit 8 | 9 | ## Present 10 | @amiller-gh (Adam Miller) 11 | @jennschiffer (Jenn Schiffer, community engineer glitch, https://glitch.com/forteams) 12 | @bnb (Tierney Cyren) 13 | @chowdhurian (Manil Chowdhury) 14 | @tolmasky (Francisco) 15 | @jonahmoses (Jonah Moses) 16 | 17 | ## Agenda 18 | * Potentially using an API service for website content [#31](https://github.com/nodejs/website-redesign/issues/31) 19 | * Coordinating "Getting Started" content with NodeSchool content [#18](https://github.com/nodejs/website-redesign/issues/18) 20 | * Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 21 | * Tech Exploration for In-Browser Node Playground [#12](https://github.com/nodejs/website-redesign/issues/12) 22 | * Identify topics to discuss for Collab Summit Spring 2018 [#29](https://github.com/nodejs/website-redesign/issues/29) 23 | 24 | ## Announcements 25 | 26 | * Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 27 | 28 | ### nodejs/website-redesign 29 | 30 | #### Potentially using an API service for website content [#31](https://github.com/nodejs/website-redesign/issues/31) 31 | Punted until the implementation phase. 32 | 33 | #### Coordinating "Getting Started" content with NodeSchool content [#18](https://github.com/nodejs/website-redesign/issues/18) 34 | Dropped / punted for now. 35 | 36 | #### Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 37 | - Two options here: Funds through the foundation for hiring a design firm, or community submissions. 38 | - Two-pronged approach, we will start the public call for designers now and also begin the process of requesting funds now as a backup (ETA ~3mo if needed) 39 | - Put the infrastructure in place to handle the influx of design submissions 40 | - Make this call available outside of Github 41 | - Make Call for Proposals ready to launch by date of the Collab Summit. Launch at Collab Summit 42 | 43 | #### Tech Exploration for In-Browser Node Playground [#12](https://github.com/nodejs/website-redesign/issues/12) 44 | - Jenn Schiffer presented a bit of history around Glitch and their platform. See: https://glitch-nodejsorg.glitch.me/ 45 | - Glitch has no lock-in. Everything can be exported to github or downloaded in a zip. 46 | - Existing features are free in perpetuity. “For Teams” to be launched as paid. It will be available to Nodejs.org for free. 47 | - Glitch would make it the BE more visible to frontend developers. 48 | - related: https://github.com/nodejs/website-redesign/issues/39 49 | - Eg. Runkit to improve docs, Glitch to make interactive Getting Started content 50 | 51 | #### Identify topics to discuss for Collab Summit Spring 2018 [#29](https://github.com/nodejs/website-redesign/issues/29) 52 | - We’ll be at the collab summit! 53 | - Yes, the summit should be live streamed and we will have meeting notes 54 | - Call for proposals for the in-person meeting’s content 55 | - Let's target the Collab Summit for launching our design CTA 56 | 57 | ## Action Items 58 | 59 | * Building on [#12](https://github.com/nodejs/website-redesign/issues/12): Create Generic “Getting Started Content” Ticket 60 | * Building on [#15](https://github.com/nodejs/website-redesign/issues/15): Draft the Call for Proposals 61 | * Building on [#15](https://github.com/nodejs/website-redesign/issues/15): Tierney talk to Mark Hinkle 62 | 63 | ## Q&A, Other 64 | 65 | * Glitch demo: https://glitch-nodejsorg.glitch.me/ 66 | 67 | ## Upcoming Meetings 68 | 69 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 70 | 71 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 72 | -------------------------------------------------------------------------------- /meetings/2018-05-10.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-05-10 2 | 3 | ## Links 4 | 5 | * **Recording**: https://youtu.be/CnccqFY2HFw 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/40 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1nBFsEmAdSAhqBoHXCpC8qAHbXLTJGieGdpBi2M-msyI/edit 8 | 9 | ## Present 10 | 11 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 12 | 13 | - Tierney Cyren (@bnb) 14 | - Adam Miller (@amiller-gh) 15 | - Dhruv Jain (@maddhruv) 16 | - Agiri Abraham Jr (@codeekage) 17 | - Manil (@chowdhurian) 18 | - Mark Hinkle 19 | 20 | ## Agenda 21 | 22 | * Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 23 | * Tech Exploration for In-Browser Node Playground [#12](https://github.com/nodejs/website-redesign/issues/12) 24 | * Extended Color Palette [#42](https://github.com/nodejs/website-redesign/issues/42) 25 | * Identify topics to discuss for Collab Summit Spring 2018 [#29](https://github.com/nodejs/website-redesign/issues/29) 26 | * Discuss Meeting Time 27 | 28 | ## Announcements 29 | 30 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 31 | 32 | ### nodejs/website-redesign 33 | 34 | * Website Wireframes [#15](https://github.com/nodejs/website-redesign/issues/15) 35 | Removed from agenda, since we’ve moved on to Design 36 | * Tech Exploration for In-Browser Node Playground 37 | [#12](https://github.com/nodejs/website-redesign/issues/12) 38 | Removed from Agenda, since we’ve moved on to design 39 | * Extended Color Palette [#42](https://github.com/nodejs/website-redesign/issues/42) 40 | 41 | What is / will be the CommComm's process for approving / adopting design system changes like this? 42 | Most design system changes we make won't effect brand related material, this one does. (In a very limited way, and for very good reasons – read the post!) Does this introduce any other considerations for adoption? 43 | The solution uses an open source color library as a foundation for its design. Does this introduce any other considerations for adoption? 44 | What do you think of the extended color palette solution as a whole? I love hearing feedback on design theory and brand alignment, please share your thoughts freely 45 | 46 | - Ask to join marketing team meeting 47 | - Doesn’t look like it will conflict with existing brand 48 | 49 | Dhruv: Do we fork existing libraries and keep it in Node.js so we have more control over design features? 50 | Adam / Tierney: We want to minimize support costs! Where possible, lets point out to OSS we’re leveraging and calling “standard” to reduce our maintenance burdon. 51 | 52 | * Identify topics to discuss for Collab Summit Spring 2018 [#29](https://github.com/nodejs/website-redesign/issues/29) 53 | 54 | Francisco: Parallel bug to getting started content – what is the getting started experience? What are priorities of “getting started” and docs? 55 | 56 | Tierney: Good place to coordinate with TSC and other members across org about how to maintain docs. 57 | 58 | - Intend to make docs more accessible 59 | - Developing user personas could support the case of making the docs more readable and accessible 60 | - Good time to work with i18n as well 61 | 62 | * Discuss Meeting Time 63 | Agreed to push 1hr back to not torture our USA West Coast members 64 | 65 | * Corporate Design Resource Donations 66 | Tierney: Raised the possibility of soliciting designer resource donations from corporate foundation members. 67 | Francisco: Stripe may be interested in providing these resources as well, on a well-defined timeline. Will talk with leads today and report back. 68 | Adam: This WG should function, among other things, as a design management body so as we have resources rotate in and out we still have a cohesive and unified project direction – we will happily take any resources we can get! There is always work :) 69 | 70 | ## Q&A, Other 71 | 72 | ## Upcoming Meetings 73 | 74 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 75 | 76 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 77 | 78 | -------------------------------------------------------------------------------- /meetings/2018-05-24.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-05-24 2 | 3 | ## Links 4 | 5 | * **Recording**: https://youtu.be/2gqCrBBiavs 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/50 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1gcQExgTMVkDx440IvfQOmQ9hLxMcd7Y2mCfj-Jp270s/edit 8 | 9 | ## Present 10 | 11 | - @amiller-gh 12 | - @bnb 13 | - @chowdhurian 14 | - @detrohutt 15 | - @maddhruv 16 | 17 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 18 | 19 | ## Agenda 20 | 21 | ## Announcements 22 | 23 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 24 | 25 | ### nodejs/website-redesign 26 | 27 | * Node.js Extended Color Palette [#42](https://github.com/nodejs/website-redesign/issues/42) 28 | 29 | * Identify topics to discuss for Collab Summit Spring 2018 [#29](https://github.com/nodejs/website-redesign/issues/29) 30 | - Adam and Manil will iterate over the weekend 31 | - Greg Wallace in marketing for Linux Foundation would be welcome for the messaging update 32 | - Make an invitation list of stakeholders. Runkit team is coming specifically for this session. 33 | - Add “Improve docs” to list of discussion items. Maybe a separate session. 34 | 35 | * Design update 36 | - Runkit will secure design resources. We’ll followup by email. 37 | 38 | ## Q&A, Other 39 | 40 | ## Upcoming Meetings 41 | 42 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 43 | 44 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 45 | 46 | -------------------------------------------------------------------------------- /meetings/2018-05-31.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-05-31 at the Node Collaborators Summit 2 | 3 | ## Links 4 | 5 | * **Recording**: `` 6 | * **Slides**: https://docs.google.com/presentation/d/1gGwqydeSHa8CsqZW49X9u7AL0BUrxuao-oZXYox2c5k/edit 7 | * **GitHub Issue**: https://github.com/nodejs/summit/issues/89 8 | * **Minutes Google Doc**: https://docs.google.com/document/d/1vqo9KOkyKP8q9cirpjqEcYnuv1NpUClPhFgEUioPMXc/edit 9 | 10 | ## Present 11 | @amiller-gh (Adam Miller) 12 | @chowdhurian (Manil Chowdhury) 13 | @tolmasky (Francisco Tolmasky) 14 | @add1sun (Addison Berry) 15 | @pouwerkerk (Pieter Ouwerkerk) 16 | @erulabs (Seandon Mooy) 17 | @me1000 (Randy Luecke) 18 | @tlobinger (Thomas Lobinger) 19 | 20 | ## Agenda 21 | 22 | * progress overview 23 | * content-focused discussion on Getting Started Tutorials 24 | * user-persona brainstorming session 25 | * logical topics for pages, tutorials, and scoped documentation 26 | 27 | ## Minutes 28 | 29 | **Adam**: This is a content-focused discussion on Getting Started Tutorials, and a 30 | high-level overview of progress. Then figure out user-personas (who’s coming to 31 | the site and why) and stakeholders and logical topics. Manil and I have been 32 | approaching this from a product-oriented flow. Process so far: Info gathering, 33 | then UX, and wireframes, then emerged voice and tone guidelines. Current phase: 34 | UI/content generation focus (high-fidelity mocks for the website; color palette, 35 | iconography, design system). RunKit/Stripe has given resources for a designer (3 36 | months) for this process. This leaves the content section. The IA discussions 37 | have left us desiring content for guides. 38 | 39 | **Greg**: What does IA stand for? 40 | 41 | **Adam**: Information Architecture. 42 | 43 | **Adam**: A couple blockers we can see in the future. Issue 44 | [#13](https://github.com/nodejs/website-redesign/issues/13), is most important. 45 | The tech exploration is ongoing ([#12](https://github.com/nodejs/website- 46 | redesign/issues/12)). There will almost certainly be some religious debates 47 | (what should we be documenting), should we have an Express example? These are 48 | big questions, and we should have these offline. 49 | 50 | **Adam**: First exercise: who are the stakeholders? We want to update the Node.js 51 | tagline. It does not invite or draw in new users. 52 | 53 | (Brainstorming Exercises) 54 | 55 | **Adam**: Opening up to discussion. What did you all think about these exercises? 56 | 57 | **Addison**: The content on the website doesn’t explain what Node is well today. 58 | 59 | **Francisco**: Does anyone do a good job of this today? 60 | 61 | **Seandon**: Rust. 62 | 63 | **Adam**: Are we doing a disservice to people who are learning not 64 | 65 | **Seandon**: Maybe an `http` example? Or Express? 66 | 67 | **Thomas**: I know what Apache and Tomcat are, I expect people may get the wrong 68 | impression of what Node is. 69 | 70 | **Addison**: I was a PHP developer, I didn’t understand what the 71 | application/possibilities of Node was, but this is the selling point. The 72 | problems of taking people down a prescribed path is you close some of the 73 | options. Imagine taking people through all these contexts and possibilities 74 | without making people walk far down a single possibilities. 75 | 76 | **Thomas**: Like a dating site, almost. 77 | 78 | **Francisco**: I don’t want the paralysis of choice—the first date if you will. 79 | 80 | **Addison**: Yeah, like one quick tutorial, then all the choices. 81 | 82 | **Francisco**: And choose a particularly good and expressive example. 83 | 84 | **Seandon**: Event-based, non-blocking examples are where Node shines, so we 85 | should emphasize these. 86 | 87 | **Francisco**: And use the latest and greatest syntax: async/await. Things you’re 88 | not going to find elsewhere. 89 | 90 | **Greg**: And answer the question, why you should care. First that, then go to the 91 | tutorial. 92 | 93 | **Thomas**: In the dating example I said, painting the picture of a person, 94 | instead of documentation reading giving user stories and something people can 95 | relate to. 96 | 97 | **Adam**: I really want to find users that fit into these groups and take pictures 98 | and create these stories. 99 | 100 | **Greg**: I can probably help with that. We ask in the annual survey if people 101 | would like to be contacted. 102 | 103 | **Adam**: I’d definitely appreciate the help. In that survey, how do these 104 | categories map to users surveyed? 105 | 106 | **Greg**: We don’t ask all these categories, but three main ones. 107 | 108 | **Adam**: There’s also the legal questions too… 109 | 110 | **Greg**: Yeah, Linux Foundation can add to that. 111 | 112 | **Addison**: Definitely talk to Dan in the User Feedback group. 113 | 114 | **Adam**: (wrapping up) We’ll go through all these and come up with actual content 115 | for these topics listed. Maybe it makes sense to make a pitch deck for 116 | stakeholders. 117 | 118 | **Greg**: Maybe we could use a CMS, for those who aren’t good with PRs. 119 | 120 | **Adam**: We have an open issue for thinking of using a CMS. So we’re definitely 121 | looking into this! What option we choose will also depend on budget. 122 | -------------------------------------------------------------------------------- /meetings/2018-09-13.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-09-13 2 | 3 | ## Links 4 | 5 | * **Recording**: https://www.youtube.com/watch?v=Ye3_j4LkxDg 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/89 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1Sk_Ni8l_z0l7BGzvKqX8Kr9_v-eVA-aZJJn95fNqd-c/edit 8 | 9 | ## Present 10 | 11 | - Manil Chowdhury (@chowdhurian) 12 | - Tierney Cyren (@bnb) 13 | - Adam Miller (@amiller-gh) 14 | - Francisco Tomalsky (@tomalsky) 15 | 16 | ## Agenda 17 | 18 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 19 | 20 | ### nodejs/node 21 | 22 | * Creating a branch of the Docs using RunKit [#21723](https://github.com/nodejs/node/issues/21723) 23 | 24 | Progress is good! PR is made. Only things left is bikeshedding. 25 | PR: https://github.com/nodejs/node/pull/22831 26 | 27 | Adam: Live demo of changes would be nice, or at least screenshots for visual review. 28 | 29 | Tierney: Example of syntax highlight here: https://nodejs.org/en/docs/guides/nodejs-docker-webapp/ 30 | 31 | **ACTION ITEM:** @tomalsky to provide screenshots or live demo for visual review on PR 22831. 32 | 33 | ### nodejs/website-redesign 34 | 35 | * JS Interactive Community Corner Topics / Ideas for Website Redesign [#80](https://github.com/nodejs/website-redesign/issues/80) 36 | 37 | Adam: We need to decide if we're doing a scattershot review or a deep dive in this session. 38 | 39 | Manil: Lets come back to this at the end of the meeting and see what makes most sense. 40 | 41 | > _Narrator: The never came back to this..._ 42 | 43 | * Consuming localized docs from `nodejs-i18n` module [#76](https://github.com/nodejs/website-redesign/issues/76) 44 | 45 | No major updated here. Removing label. Will integrate when we start buildout. 46 | 47 | * List of Getting Started Content titles, grouped by stakeholder [#60](https://github.com/nodejs/website-redesign/issues/60) 48 | 49 | Adam: Mentioned LinkedIn Learning intro videos offer. 7-10 custom recorded videos to introduce major content type areas. 50 | 51 | Manil: Can’t prioritize current list. Is there a tool we can use to help prioritize here? This one works well: https://www.uservoice.com/ 52 | 53 | Tierney: May get a little confusing, but could be useful! 54 | 55 | **ACTION ITEM:** Manil set up demo of feedback system (User Voice?), comment in this issue. 56 | 57 | * Node.js Extended Color Palette [#42](https://github.com/nodejs/website-redesign/issues/42) 58 | 59 | Stub ticket to talk about design! We're going to show off iteration 1 designs to CommComm for initial feedback on the Sept. 20th meeting. Illustration and mushy "look and feel" type of explorations ongoing. (Side note: Working on an octacat-esque mascot :tada:) 60 | 61 | ### PR Review 62 | 63 | * Instruction for installation Node on Mac [#85](https://github.com/nodejs/website-redesign/pull/85) 64 | 65 | Tierney provided extra context to add. Manil will work with the author at their next meetup! 66 | 67 | * Add doc for monitoring with Elastic APM [#84](https://github.com/nodejs/website-redesign/pull/84) 68 | 69 | **ACTION ITEM:** Tierney – start draft of monitoring conceptual information doc, link to this doc. 70 | 71 | * using-node-with-framework [#83](https://github.com/nodejs/website-redesign/pull/83) 72 | 73 | **ACTION ITEM:** Manil – follow up with author of PR #83. 74 | 75 | 76 | ## Q&A, Other 77 | 78 | ### Adam: Meetup docs hackathons? 79 | 80 | **ACTION ITEM:** Adam make ticket for Meetup docs hackathons discussion. 81 | 82 | **ACTION ITEM:** Tierney link to content for #85 83 | 84 | ### Manil: Activity on Voice and Tone? 85 | 86 | **ACTION ITEM:** Drive engagement on #13, request PR from @eojthebrave 87 | 88 | ## Upcoming Meetings 89 | 90 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 91 | 92 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 93 | 94 | -------------------------------------------------------------------------------- /meetings/2018-09-27.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-09-27 2 | 3 | ## Links 4 | 5 | * **Recording**: https://www.youtube.com/watch?v=dTh1VPFJgHY 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/97 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1dqeoPhKc7PfX8zh9UzkkFKchTcUvAZhINB39ExqOk6I/edit 8 | 9 | ## Present 10 | 11 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 12 | 13 | * Manil Chowdhury (@chowdhurian) 14 | * Tierney Cyren (@bnb) 15 | * Adam Miller (@amiller-gh) 16 | * Francisco Tomalsky (@tomalsky) 17 | 18 | ## Agenda 19 | 20 | ## Announcements 21 | 22 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 23 | 24 | ### nodejs/node 25 | 26 | * Creating a branch of the Docs using RunKit [#21723](https://github.com/nodejs/node/issues/21723) 27 | 28 | Blocked on ESLint issue. 29 | 30 | ### nodejs/website-redesign 31 | 32 | * Meeting Action Items: 2018-09-13 [#90](https://github.com/nodejs/website-redesign/issues/90) 33 | 34 | ACTION ITEM: @ammiller-gh Figure out social blast for docs CTA 35 | ACTION ITEM: @manil – seed feedback form with existing data 36 | 37 | * Collab Summit: Website Redesign Breakout Session [#88](https://github.com/nodejs/website-redesign/issues/88) 38 | 39 | ACTION ITEM: @ammiller-gh – Determine format for Breakout session. Make Slide deck to collaborate on. Use for #66 40 | 41 | * JS Interactive Community Corner Topics / Ideas for Website Redesign [#80](https://github.com/nodejs/website-redesign/issues/80) 42 | * Walkthrough in CommComm and TSC meeting? [#66](https://github.com/nodejs/website-redesign/issues/66) 43 | 44 | ACTION ITEM @ammiller-gh – Talk to dawson about TSC meeting on the 3rd (Edit: This has passed. After N+JSI?) 45 | 46 | * User Feedback: Node.js Docs Survey [#61](https://github.com/nodejs/website-redesign/issues/61) 47 | 48 | ACTION ITEM @ammiller-gh – Create google form / comment on form with Monday deadline. 49 | 50 | * List of Getting Started Content titles, grouped by stakeholder [#60](https://github.com/nodejs/website-redesign/issues/60) 51 | 52 | ACTION ITEM @ammilelr-gh – Reach out to flavio. 53 | 54 | ## Q&A, Other 55 | 56 | ## Upcoming Meetings 57 | 58 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 59 | 60 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 61 | 62 | -------------------------------------------------------------------------------- /meetings/2018-1-17.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2019-01-17 2 | 3 | ## Links 4 | 5 | * **Recording**: 6 | * **GitHub Issue**: $GITHUB_ISSUE$ 7 | * **Minutes Google Doc**: $MINUTES_DOC$ 8 | 9 | ## Present 10 | 11 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 12 | 13 | * Manil (@chowdhurian) 14 | * Jenn (@jennschiffer) 15 | * Rachel (@rromoff) 16 | * Myles Borins (@MylesBorins) 17 | * Mohit Bajoria (@mbj36) 18 | * Tierney Cyren (@bnb) 19 | * Matt Claypotch (@potch) 20 | 21 | ## Agenda 22 | 23 | ## Announcements 24 | 25 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 26 | 27 | ### nodejs/website-redesign 28 | 29 | * \[Discussion\] - Tech Stack Consideration [#107](https://github.com/nodejs/website-redesign/issues/107) 30 | 31 | 32 | 33 | * Idea: Host Docs Hackathons [#99](https://github.com/nodejs/website-redesign/issues/99) 34 | * User Feedback: Node.js Docs Survey [#61](https://github.com/nodejs/website-redesign/issues/61) 35 | 36 | * Node.js Foundation Website IA 37 | - Latest from Medium 38 | - Homepage content – ensure it is covered by new HP. 39 | - Mention of member of the $FOUNDATION! In the “history” section of Learn? 40 | - Governance section? TSC / CommComm / WGs? 41 | - Individual membership!?!?!?!? Needs more definition. 42 | - Application Showcase 43 | - Tierney: Has this driven value? If it has, awesome, if it hasn’t drop / improve? 44 | - Certification Program 45 | - Spotlight Videos – maybe? Rachel: How do they perform? Will get numbers. Largely just a pivot page to YouTube – likely cut. 46 | - Announcements page – maybe just live on Medium? How to reconcile with release announcement page? Can we automate? Can we list latest medium articles anyway? 47 | - In the news. Tierney: Don’t think this is valuable for the nodejs website itself. Can live on new $FOUNDATION website. Not the target audience. Cut. 48 | - Events! Keep. Make better. 49 | - Newsletter: Foundation version likely going away with the merger, can possibly be a CommComm owned newsletter. Mohit: Can be a subscribe box/button somewhere, not a full page. 50 | - Speakers Buerau: Need to check status post Zibby. 51 | - Resources for Event Org: Keep. Make better. Talk more. 52 | - Store: keep link. 53 | - Keep: Social media links. 54 | 55 | 56 | ## Q&A, Other 57 | 58 | ## Upcoming Meetings 59 | 60 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 61 | 62 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 63 | 64 | -------------------------------------------------------------------------------- /meetings/2018-10-13.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Collab Summit Session 2018-10-13 2 | 3 | ## Links 4 | 5 | * **Minutes Google Doc**: https://docs.google.com/document/d/16eRahz4dmoEBCyISoRr721Rg9gjCEXVRKVsz0RvxcUw/edit 6 | 7 | # Collab Summit 8 | 9 | ## Present 10 | 11 | Francisco @tolmasky 12 | Joey @beefymcpound / @joeyellis 13 | Stephen @qard 14 | Manil @chowdhurian 15 | Adam @amiller-gh 16 | Jeremiah @fishrock123 17 | Tierney @bnb 18 | Joe @eojthebrave 19 | Matheus @mmarchini 20 | 21 | ## Goals 22 | 23 | * Each person who wants to participate leaves with an action item, of large or small scope. May or may not include being onboarded. 24 | 25 | ## Notes 26 | 27 | ### Requirements gathering 28 | 29 | We would like to do it so that the next time a redesign happens, which it will, you don’t have to throw everything out. Should be like a UI consuming docs in markdown. 30 | 31 | Does content need to live with the repos that it describes? 32 | 33 | There is also content that is an artifact of something else in the ecosystem. e.g.) a list of historical builds, change records, code coverage stats. These will need to be ingested from wherever they live currently. 34 | 35 | Should the new website facilitate content from projects like llnode and N-API? Right now the content for these projects lives in their individual GitHub repos. Can/should it be surfaced on the main site? There should be policies/guidelines in place that outline what projects can surface their content onto the main site. Allow groups to opt-in to doing this rather than making it a requirement. 36 | 37 | ### Hosting sub-projects in the site 38 | 39 | * N-API 40 | * llnode 41 | * node-gyp 42 | * canary-in-the-goldmine 43 | * nan 44 | * (docker images we publish) 45 | 46 | ## Q&A, Other 47 | 48 | ## Upcoming Meetings 49 | 50 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 51 | 52 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar -------------------------------------------------------------------------------- /meetings/2018-12-06.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2018-12-06 2 | 3 | ## Links 4 | 5 | * **Recording**: 6 | * **GitHub Issue**: $GITHUB_ISSUE$ 7 | * **Minutes Google Doc**: $MINUTES_DOC$ 8 | 9 | ## Present 10 | * Tierney Cyren (@bnb) 11 | * Manil (@chowdhurian) 12 | * Lidor (@lidoravitan) 13 | 14 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 15 | 16 | ## Agenda 17 | 18 | ## Announcements 19 | 20 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 21 | 22 | ### nodejs/community-committee 23 | 24 | * Node.js Contributor Cards [#428](https://github.com/nodejs/community-committee/issues/428) 25 | 26 | Physical card to link to same site that will change 27 | Link needs to be more focused. When someone is interested in contributing, the card should have one purpose, get someone who is interested to the resource they need. 28 | This “card” could be one of the items on the community page. 29 | We should make sure people don’t have to search the repo for the information they need. 30 | Navigating the repo needs prior knowledge 31 | Action item: Manil to deploy site 32 | Action item: Tierney to design card 33 | Action item: Lidor to review 34 | 35 | ### nodejs/website-redesign 36 | 37 | * \[Discussion\] - Tech Stack Consideration [#107](https://github.com/nodejs/website-redesign/issues/107) 38 | 39 | Support expressed for Gatsby around it’s new company and expectation of longevity 40 | 41 | * Idea: Host Docs Hackathons [#99](https://github.com/nodejs/website-redesign/issues/99) 42 | 43 | Action item: Manil to write a report about how the docs hackathon went after NodeSchool which Tierney can iterate on later. Also open to anyone else :) 44 | 45 | * User Feedback: Node.js Docs Survey [#61](https://github.com/nodejs/website-redesign/issues/61) 46 | 47 | One of the suggestions was to include a happy-neutral-sad face on the docs. Good use-case for a serverless architecture which could be good blog content for the Node.js Collection. Serverless companies can contribute and talk about using Node.js on their platform. 48 | Person may know what’s wrong but not not have a way to request edits 49 | No action items in website-redesign. 50 | 51 | 52 | ## Q&A, Other 53 | 54 | ## Upcoming Meetings 55 | 56 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 57 | 58 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. -------------------------------------------------------------------------------- /meetings/2019-02-28.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2019-02-28 2 | 3 | ## Links 4 | 5 | * **Recording**: 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/146 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1JizrFXDqS7T3RzwuGELUBytBD3fBHn-Pzc2XuY5SrS8/edit 8 | 9 | 10 | ## Present 11 | 12 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 13 | 14 | 15 | ## Agenda 16 | 17 | ## Announcements 18 | 19 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 20 | nodejs/nodejs.dev 21 | 22 | * Turning off "merge" button [#103](https://github.com/nodejs/nodejs.dev/issues/103) 23 | * Review the prettierrc and adapt "best practice" 24 | [#44](https://github.com/nodejs/nodejs.dev/issues/44) 25 | 26 | Onur: Changing one rule, investigating tslint<->prettier automation, re-running #97 and pulling in all / closing issues. 27 | 28 | * How do we want to add new members? 29 | [#127](https://github.com/nodejs/nodejs.dev/issues/127) 30 | 31 | No objections on the channel to process in the ticket. 3 PRs is guidance, not policy. 32 | Onur: How do you deal with inactive people? 33 | Sagir: 3 non-trivial PRs? 34 | Adam: Attendance policy? 35 | No objections to the attendance policy. 36 | TODO: Adam to codify and PR. (maybe use `core` for inspiration) 37 | 38 | * No periods at the end of commit messages [#150](https://github.com/nodejs/nodejs.dev/issues/150) 39 | 40 | No objections on call. 41 | TODO: Sagir to add a link to CC and update the decision on no periods in CONTRIBUTING.md 42 | 43 | ### nodejs/website-redesign 44 | 45 | * Migrate Foundation Website Content to New Site [#134](https://github.com/nodejs/website-redesign/issues/134) 46 | 47 | Removing label. Will keep this in mind as we design next pages. 48 | 49 | * User Feedback: Node.js Docs Survey 50 | [#61](https://github.com/nodejs/website-redesign/issues/61) 51 | 52 | Consensus: Still want to execute on this. 53 | TODO: Agiri to take to User Feedback meeting tomorrow. 54 | 55 | * New Home: Nodejs.dev [#147](https://github.com/nodejs/website-redesign/issues/147) 56 | 57 | Sagir: Wasn’t aware of the sister repo before – consolidating would be good. 58 | Ahmad: Seconded – meeting notes in the .dev repo would encourage contribution. 59 | Agiri: A little concerned about clutter, moving meeting minutes in to dev repo – will need to work on content structure to keep organized, otherwise ok. 60 | TODO: Adam to move over content 61 | 62 | ## Q&A, Other 63 | 64 | ## Upcoming Meetings 65 | 66 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 67 | 68 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 69 | 70 | -------------------------------------------------------------------------------- /meetings/2019-03-14.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2019-03-14 2 | 3 | ## Links 4 | 5 | * **Recording**: 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/152 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1bYKtO1T5iB0q6P8yLYUtiHqxNgx-T0M6xnLu4mdoy7k/edit 8 | 9 | ## Present 10 | 11 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 12 | 13 | ## Agenda 14 | 15 | ## Announcements 16 | 17 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 18 | 19 | ### nodejs/website-redesign 20 | 21 | * New Home: Nodejs.dev? [#147](https://github.com/nodejs/website-redesign/issues/147) 22 | 23 | Recap earlier convo on issue thread. 24 | Question about who is responsible for Nodejs.dev 25 | We’ll need to have a governance chat. It will eventually merge into nodejs.org 26 | Nodejs.dev could be used as a starting point for devs later. 27 | AI: Add website-redesign intro to the nodejs.dev repo 28 | 29 | 30 | * User Feedback: Node.js Docs Survey [#61](https://github.com/nodejs/website-redesign/issues/61) 31 | 32 | AI: Sync with user-feedback initiative on whether the user feedback meetups can incorporate this 33 | 34 | ### nodejs/nodejs.dev 35 | 36 | * How do we want to add new members? [#127](https://github.com/nodejs/nodejs.dev/issues/127) 37 | 38 | Self-nomination is more encouraging. 39 | Getting nomination from existing contributors could be become a barrier or create a restrictive culture. 40 | No decision made, tabled for next meeting. 41 | 42 | * Navigation / Section Proposal [#169](https://github.com/nodejs/nodejs.dev/issues/169) 43 | 44 | For now, we need more data on this issue so keeping it open for now. 45 | 46 | 47 | ## Q&A, Other 48 | 49 | ## Upcoming Meetings 50 | 51 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 52 | 53 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 54 | 55 | -------------------------------------------------------------------------------- /meetings/2019-03-28.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2019-03-28 2 | 3 | ## Links 4 | 5 | * **Recording**: 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/156 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1HeV7f_lg0h9YFfrtRj0QCiTCcFJZ77rvWuuaYnbj6Vg/edit 8 | 9 | ## Present 10 | 11 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 12 | 13 | - Manil Chowdhury (@keywordnew) 14 | - Adam (@amiller-gh) 15 | - LaRuaNa (@LaRuaNa) 16 | - Zeke (@zeke) 17 | - Sagir (@sagirk) 18 | - Hassan Sani (@iNidAName) 19 | - Ahmad Awais (@AhmadAwais) 20 | - Maedah Batool (@MaedahBatool) 21 | 22 | 23 | ## Agenda 24 | 25 | ## Announcements 26 | 27 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 28 | 29 | ### nodejs/website-redesign 30 | 31 | * CFP for Collab Summit is live! Let's answer the Call for Proposals 📣 [#155](https://github.com/nodejs/website-redesign/issues/155) 32 | 33 | Manil: Pace picked up quickly, would be good to see if we’re still functioning well. 34 | Sagir: Recap of the process so far and future plans. 35 | Onur: Workshop to get new people on board – Gatsby / React tutorial? 36 | Adam: In the process improve onboarding docs? 37 | Onur: Get good first issues in the issue queue. 38 | Manil: Tuts will be for folks already familiar. 39 | Adam: How we want to tackle API docs 40 | Zeke: How to consume localized API docs 41 | 42 | * User Feedback: Node.js Docs Survey [#61](https://github.com/nodejs/website-redesign/issues/61) 43 | 44 | ### nodejs/nodejs.dev 45 | 46 | * Navigation / Section Proposal [#169](https://github.com/nodejs/nodejs.dev/issues/169) 47 | 48 | * Discussion: report code coverage during travis builds [#206] https://github.com/nodejs/nodejs.dev/issues/206 49 | 50 | * Discussion: Alternate solutions to provide credit [#201](https://github.com/nodejs/nodejs.dev/issues/201) 51 | 52 | Awais: We can probably use the `.png` after GitHub user profile links to generate a profile image (provided we have the consent, something we could automate via open source consent bot). 53 | 54 | E.g. 55 | 56 | Profile: https://github.com/AhmadAwais 57 | Profile Image: https://github.com/AhmadAwais.png 58 | Profile Image Resize: https://github.com/AhmadAwais.png?size=90 59 | 60 | Tested the API calls via: 61 | 62 | ```sh 63 | curl https://github.com/AhmadAwais.png 64 | curl https://api.github.com/rate_limit 65 | ``` 66 | Doesn't seem to be rate limited by looking at the rate.remaining property. 67 | 68 | ## Q&A, Other 69 | 70 | ## Upcoming Meetings 71 | 72 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 73 | 74 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 75 | 76 | -------------------------------------------------------------------------------- /meetings/2019-04-25.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2019-04-25 2 | 3 | ## Links 4 | 5 | * **Recording**: https://www.youtube.com/watch?v=8ayWJMjvR0I 6 | * **GitHub Issue**: https://github.com/nodejs/website-redesign/issues/164 7 | * **Minutes Google Doc**: https://docs.google.com/document/d/1akTb1L5wrM1I-l94kKw-mLLG7dn3WLhcOtPvtn1lTnI/edit 8 | 9 | ## Present 10 | 11 | Website Redesign Strategic Initiative Team: @nodejs/website-redesign 12 | 13 | * Sagir Khan (@sagirk) 14 | * Ben Michel (@obensource) 15 | * Manil Chowdhury (@keywordnew) 16 | * Tierney Cyren (@bnb) 17 | * Oscar Gonzalez (@ogonzal87) 18 | 19 | ## Agenda 20 | 21 | ## Announcements 22 | 23 | *Extracted from **wr-agenda** labeled issues and pull requests from the **nodejs org** prior to the meeting. 24 | 25 | ### nodejs/website-redesign 26 | 27 | #### Node.js Foundation Website Redesign Brief 2019-03-28 [#157](https://github.com/nodejs/website-redesign/issues/157) 28 | * There is a form to share 29 | * The User Feedback Initiative can help with privacy issues 30 | * Foundation will share through org twitter 31 | * Existing analytics data for the current .org site shows that most people stay on the homepage. Only 4pc go to docs. Most are new visitors. Good opportunity to direct to tutorials. 32 | * https://github.com/nodejs/website-redesign/issues/45 33 | * 
https://github.com/nodejs/website-redesign/issues/4 34 | * Begun working on a stylesheet (color, iconography, grid, typography, and so on) 35 | * our assets: https://nodejs.org/en/about/resources/
 36 | 37 | #### Create data contract for how API documentation will be consumed [#158](https://github.com/nodejs/website-redesign/issues/158) 38 | 39 | #### Consuming localized docs from `nodejs-i18n` module [#76](https://github.com/nodejs/website-redesign/issues/76) 40 | 41 | * Todo: Ben to resolve #76, set up website-redesign/i18n ‘consuming the i18n module’ meeting. 42 | 43 | ### nodejs/nodejs.dev 44 | 45 | #### Self-Nomination to add BeniCheni as Collaborator? [#243](https://github.com/nodejs/nodejs.dev/issues/243) 46 | * Resolved 47 | 48 | * https://github.com/nodejs/website-redesign/issues/15 49 | * “Does your company use Node.js?” is better pushed by the CommComm 50 | * Todo: Tierney to create an issue in CommComm 51 | 52 | 53 | 54 | ## Q&A, Other 55 | 56 | ## Upcoming Meetings 57 | 58 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 59 | 60 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 61 | 62 | -------------------------------------------------------------------------------- /meetings/2019-06-06.md: -------------------------------------------------------------------------------- 1 | # Node.js Foundation Website Redesign Strategic Initiative Meeting 2019-06-06 2 | 3 | ## Links 4 | 5 | * **Recording**: 6 | * **GitHub Issue**: $GITHUB_ISSUE$ 7 | * **Minutes Google Doc**: $MINUTES_DOC$ 8 | 9 | ## Present 10 | @LaRuaNa 11 | @jonchurch 12 | 13 | * Website Redesign Strategic Initiative Team: @nodejs/website-redesign 14 | 15 | 16 | 17 | 18 | ## Agenda 19 | 20 | ## Announcements 21 | 22 | *Extracted from **wr-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. 23 | 24 | ### nodejs/website-redesign 25 | 26 | * Create data contract for how API documentation will be consumed [#158](https://github.com/nodejs/website-redesign/issues/158) 27 | What format are the docs in currently? Are they managing metadata, what is that metadata, what does it do? Do we intend to use it? 28 | 29 | ### nodejs/nodejs.dev 30 | 31 | * SPIKE: In Our Perfect World, In What Format Would the API Be Documented? [#258](https://github.com/nodejs/nodejs.dev/issues/258) 32 | 33 | What metadata do we want to record? That could inform what format we use. Maybe frontmatter? Let’s discuss at the next meeting when we have more people 34 | 35 | * Integrate Algolia Code Search [#257](https://github.com/nodejs/nodejs.dev/issues/257) 36 | 37 | How to integrate algolia indexing with the different versions of the docs? v12 vs v10 etc 38 | The search should be linked to the current version of the docs that you are looking at. 39 | We don’t know yet how to support searching in multiple versions of the docs 40 | 41 | * Integrate API JSON as an async data source [#255](https://github.com/nodejs/nodejs.dev/issues/255) 42 | Skipping, because it requires research and context that we don’t have in this meeting 43 | 44 | * Select and Integrate an i18n Library [#254](https://github.com/nodejs/nodejs.dev/issues/254) 45 | 46 | We will create an npm package with all the text of the different languages for the documentation. 47 | We need to check if there are any complications in integrating an npm package with the gatsby i18n plugin we choose. 48 | maybe use react-intl https://github.com/formatjs/react-intl 49 | or maybe react-i18next https://github.com/i18next/react-i18next/ 50 | 51 | * chore: Eslint / Prettier integration. [#179](https://github.com/nodejs/nodejs.dev/pull/179) 52 | @LaRuaNa is working on this, needs to find the time to rewrite the code 53 | 54 | Mentoring/Pair coding program for new contributors? 55 | Maybe issue tagging? “Good first issue” 56 | Maybe livestream contributing? Show people how to get involved. Or just record a “getting started” type of resource. 57 | Ask manil about the mentoring program/intro to OSS he has worked. 58 | Maybe plan the stream ahead of time, create and tag good intro issues, select which ones we will work on live, and advertise it on twitter. 59 | 60 | Reopened the idea of merging the two repos together https://github.com/nodejs/website-redesign/issues/147 61 | 62 | 63 | There are new project boards for each page of the new site 64 | https://github.com/nodejs/nodejs.dev/projects 65 | @LaRuaNa will organize some of these 66 | 67 | Link to new design system, in progress. Click the node logo to switch between light and dark modes 68 | https://www.figma.com/proto/brsBURZIKRBj7JAmMMCz2rlz/NJ---Design-System?node-id=90%3A4958&scaling=min-zoom&redirected=1 69 | 70 | Knowledge base articles 71 | They’re being worked on in the Node.js org currently, we need to make sure these aren’t being worked on in two places. they aren’t currently linked to on the nodejs.org site, so they don’t really need to be in that repo. 72 | We could pull them into the nodejs.dev repo and work on them there. 73 | We should figure out what articles from the knowledge base we want to use, which are duplicates of what we already have, and how we want to use the knowledge base info (if at all). 74 | 75 | ## Q&A, Other 76 | 77 | ## Upcoming Meetings 78 | 79 | * **Node.js Foundation Calendar**: https://nodejs.org/calendar 80 | 81 | Click `+GoogleCalendar` at the bottom right to add to your own Google calendar. 82 | 83 | 84 | --------------------------------------------------------------------------------