{"id":18436236,"url":"https://github.com/javascript-tutorial/server","last_synced_at":"2025-05-15T13:07:57.319Z","repository":{"id":39172941,"uuid":"66103429","full_name":"javascript-tutorial/server","owner":"javascript-tutorial","description":"Server for the Modern Javascript Tutorial","archived":false,"fork":false,"pushed_at":"2025-04-13T17:59:47.000Z","size":3785,"stargazers_count":458,"open_issues_count":10,"forks_count":141,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-04-15T05:32:40.806Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://javascript.info","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/javascript-tutorial.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-08-19T18:21:01.000Z","updated_at":"2025-04-13T17:59:50.000Z","dependencies_parsed_at":"2025-04-15T02:16:04.026Z","dependency_job_id":"18e6e979-2717-4e70-96d1-682fc100ba08","html_url":"https://github.com/javascript-tutorial/server","commit_stats":{"total_commits":257,"total_committers":13,"mean_commits":19.76923076923077,"dds":"0.12840466926070038","last_synced_commit":"12069c6c6b64054b067a97457b4a587dca730f77"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-tutorial%2Fserver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-tutorial%2Fserver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-tutorial%2Fserver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javascript-tutorial%2Fserver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/javascript-tutorial","download_url":"https://codeload.github.com/javascript-tutorial/server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254346624,"owners_count":22055808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T06:10:54.576Z","updated_at":"2025-05-15T13:07:52.252Z","avatar_url":"https://github.com/javascript-tutorial.png","language":"JavaScript","readme":"# Tutorial Server\n\nHi everyone!\n\nThis is a standalone server for the javascript tutorial https://javascript.info.\n\nYou can use it to run the tutorial locally and translate it into your language.\n\nWindows, Unix systems and macOS are supported. For Windows, you'll need to call scripts with \".cmd\" extension, that are present in the code alongside with Unix versions.\n\n\n# Installation\n\n1. Install [Git](https://git-scm.com/downloads) and [Node.js](https://nodejs.org).\n\n    These are required to update and run the project.\n    For Windows just download and install, otherwise use standard OS install tools (packages or whatever convenient).\n\n    (Maybe later, optional) If you're going to change images, please install [ImageMagick](https://imagemagick.org/script/download.php), use packages for Linux or homebrew/macports for MacOS.\n\n2. Install global Node modules:\n\n    ```bash\n    npm install -g bunyan gulp@4\n    ```\n\n3. Create the root folder.\n\n    Create a folder `/js` for the project.\n\n    You can also use another directory as the root, then change the paths below: replace `/js` with your root.\n\n4. Clone the tutorial server into it:\n\n    ```bash\n    cd /js\n    git clone https://github.com/javascript-tutorial/server\n    git clone https://github.com/javascript-tutorial/engine server/modules/engine\n    ```\n\n    Please note, there are two clone commands. That's not a typo: `modules/engine` is cloned from another repository.\n\n    And please don't forget when pulling an updated server code: `modules/engine` needs to be pulled too.\n\n5. Clone the tutorial text into it.\n\n    The repository starts with the language code, e.g for the French version `fr.javascript.info`, for Russian – `ru.javascript.info`, for Chinese `zh.javascript.info` etc.\n\n    The English version is `en.javascript.info`.\n\n    The tutorial text repository should go into the `repo` subfolder, like this:\n\n    ```bash\n    cd /js/server/repo\n    git clone https://github.com/javascript-tutorial/en.javascript.info\n    ```\n\n6. Run the site\n\n    Install local NPM modules:\n\n    ```bash\n    cd /js/server\n    npm install\n    ```\n\n    Run the site with the `./edit` command with the language argument. Above we cloned `en` tutorial, so:\n\n    ```bash\n    ./edit en\n    ```\n\n    This will import the tutorial from `/js/server/repo/en.javascript.info` and start the server.\n\n    Wait a bit while it reads the tutorial from the disk and builds static assets.\n\n    Then access the site at `http://127.0.0.1:3000`.\n\n    \u003e To change the port, set the `PORT` environment variable:\n    \u003e ```bash\n    \u003e # Runs the server at http://127.0.0.1:8080\n    \u003e PORT=8080 ./edit en\n    \u003e ```\n    \u003e For Windows, read the note about environment variables below.\n\n7. Edit the tutorial\n\n    As you edit text files in the tutorial text repository (cloned at step 5),\n    the webpage will reload automatically.\n\n\n# Windows: Environment variables\n\nFor Windows, to pass environment variables, such as `PORT`, you can install `npm i -g cross-env` and prepend calls with `cross-env`, like this:\n\n```bash\ncd /js/server\ncross-env PORT=8080 ./edit en\n```\n\nIn the examples below, the commands are without `cross-env`, prepend it please, if you're on Windows.\n\nAlternatively, you can use other Windows-specific ways to set environment variables, such as a separate `set PORT=8080` command.\n\n# Change server language\n\nThe server uses English by default for navigation and design.\n\nYou can set another language it with the second argument of `edit`.\n\nE.g. if you cloned `ru` tutorial, it makes sense to use `ru` locale for the server as well:\n\n```bash\ncd /js/server\n./edit ru ru\n```\n\nPlease note, the server must support that language. There must be corresponding locale files for that language in the code of the server, otherwise it exists with an error. As of now, `ru`, `en`, `zh`, `tr`, `ko` and `ja` are fully supported.\n\n# Translating images\n\nPlease don't translate SVG files manually.\n\nThey are auto-generated from the English variant, with the text phrases substituted from `images.yml` file in the repository root, such as \u003chttps://github.com/javascript-tutorial/ru.javascript.info/blob/master/images.yml\u003e.\n\nSo you need to translate the content of `images.yml` and re-generate the SVGs using a script.\n\nHere are the steps to translate images.\n\n**Step 1.** Setup git upstream (if you haven't yet) and pull latest changes from English version:\n\n```bash\ncd /js/server/repo/zh.javascript.info # in the tutorial folder\n\ngit remote add upstream https://github.com/javascript-tutorial/en.javascript.info\n\ngit fetch upstream master\n```\n\n**Step 2.** Create `images.yml` with translations in the repository root.\n\nAn example of such file (in Russian): https://github.com/javascript-tutorial/ru.javascript.info/blob/master/images.yml\n\nThe file format is [YAML](https://learnxinyminutes.com/docs/yaml/).\n\nHere's a quote:\n\n```yaml\ncode-style.svg:  # image file name\n  \"No space\":    # English string\n    text: \"Без пробелов\" # translation\n    position: \"center\" # (optional) \"center\" or \"right\" - to position the translated string\n  \"between the function name and parentheses\":\n    position: \"center\"\n    text: \"между именем функции и скобками\"\n```\n\nAs you can see, for each image file there's a name (such as `code-style.svg`), and then goes the list of its English phrases (such as `\"No space\"`), accompanied by translations:\n\n- `text` is the translated text\n- `position` (not always needed, details will come soon) is the relative position of the text.\n\nInitially, the file may be empty, then you can fill it with images one by one.\n\nOnly the mentioned images will be translated.\n\n**Step 3.** Use the helper script to get a list of strings to translate:\n\nThe script is executed from the server root, like this:\n\n```bash\n# Adjust NODE_LANG to your language\n\n❯ NODE_LANG=zh npm run gulp -- engine:koa:tutorial:imageYaml --image code-style.svg\n```\n\nHere's an example of its output:\n\n```yml\ncode-style.svg:\n  '2': ''\n  No space: ''\n  between the function name and parentheses: ''\n  between the parentheses and the parameter: ''\n  Indentation: ''\n  2 spaces: ''\n  'A space ': ''\n  after for/if/while…: ''\n  '} else { without a line break': ''\n  Spaces around a nested call: ''\n  An empty line: ''\n  between logical blocks: ''\n  Lines are not very long: ''\n  A semicolon ;: ''\n  is mandatory: ''\n  Spaces: ''\n  around operators: ''\n  Curly brace {: ''\n  on the same line, after a space: ''\n  A space: ''\n  between: ''\n  arguments: ''\n  A space between parameters: ''\n```\n\nAs we can see, the script returns a text snippet that can be inserted into `images.yml` fully or partially.\n\nE.g. like this:\n\n```yml\ncode-style.svg:\n  'A space ': 'Пробел'\n```\n\nOr like this, if we want to position the translation in the center (see below for more examples):\n\n```yml\ncode-style.svg:\n  'A space ':\n    position: 'center'\n    text: 'Пробел'\n```\n\n**Step 4.** Run the translation task:\n\n```bash\ncd /js/server # in the server folder\n\n# adjust NODE_LANG to your language\n\nNODE_LANG=zh npm run gulp -- engine:koa:tutorial:figuresTranslate\n```\n\nThis script checks out all SVG images from `upstream` (English version) and replaces the strings inside them according to `images.yml`. So they become translated.\n\nThe new translated SVGs are the tutorial folder now, but not committed yet.\n\nYou can see them with `git status`.\n\nTake a moment to open and check them, e.g. in Chrome browser, just to ensure that the translation looks good.\n\nP.S. If an image appears untranslated on refresh, force the browser to \"reload without cache\" ([hotkeys](https://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache#Bypassing_cache)).\n\n**Step 5.** Then you'll need to `git add/commit/push` the translated SVGs, as a part of the normal translation flow.\n\n...And voilà! SVGs are translated!\n\n\u003e Normally, the translation script looks for all images listed in `images.yml`.\n\u003e To translate a single image, use the `--image` parameter of the script:\n\u003e ```bash\n\u003e # replace strings only in try-catch-flow.svg\n\u003e NODE_LANG=zh npm run gulp -- engine:koa:tutorial:figuresTranslate --image try-catch-flow.svg\n\u003e ```\n\nRead on for more advanced options and troubleshooting.\n\n## Positioning\n\n\u003e For the positioning to work, sure you have installed [ImageMagick](https://imagemagick.org/script/download.php) mentioned in the [installation](#installation) step.\n\nBy default, the translated string replaces the original one, starting in exactly the same place of the image.\n\nBefore the translation:\n\n```\n| hello world\n```\n\nAfter the translation (`你` is at the same place where `h` was, the string is left-aligned):\n\n```\n| 你好世界\n```\n\nSometimes that's not good, e.g. if the string needs to be centered, e.g. like this:\n\n```\n     |\nhello world\n     |\n```\n\nHere, the \"hello world\" is centered between two vertical lines `|`.\n\nThen, if we just replace the string, it would become:\n\n```\n     |\n你好世界\n     |\n```\n\nAs we can see, the new phrase is shorter. We should move it to the right a bit.\n\nThe `position: \"center\"` in `images.yml` does exactly that.\n\nIt centers the translated string, so that it will replace the original one and stay \"in the middle\" of the surrounding context.\n\nHere's the text with `position: \"center\"`, centered as it should be:\n```\n   |\n你好世界\n   |\n```\n\nThe `position: \"right\"` makes sure that the translated string sticks to the same right edge:\n```\nhello world |\n    你好世界 |\n```\n\nThat's also useful for images when we expect the text to stick to the right.\n\n\n## The \"overflowing text\" problem\n\nThe replacement script only operates on strings, not other graphics, so a long translated string may not fit the picture.\n\nMost pictures have some extra space for longer text, so a slight increase doesn't harm.\n\nIf the translated text is much longer, please try to change it, make it shorter to fit.\n\nIf the translated text absolutely must be longer and doesn't fit, let me know, we'll see how to adjust the picture.\n\n## Troubleshooting images translation\n\nIf you add a translation to `images.yml`, but after running the script the SVG remains the same, so that the translation doesn't \"catch up\":\n\n1. Ensure that you have the latest server code and translation repos, fetched the upstream.\n2. Check if the English version has the file with the same name. The file could have been renamed.\n3. Check that there's only 1 file with the given name in the tutorial. Sometimes there may be duplicates.\n4. Check that the translated string in `images.yml` is exactly as in SVG: use the helper script (Step 3) to extract all strings.\n\nIf it still doesn't work – [file an issue](https://github.com/javascript-tutorial/server/issues/new).\n\n# Dev mode\n\nIf you'd like to edit the server code (assuming you're familiar with Node.js), *not* the tutorial text, then there are two steps to do.\n\nFirst, run the command that imports (and caches) the tutorial:\n\n```bash\ncd /js/server\nNODE_LANG=en npm run gulp engine:koa:tutorial:import\n```\n\n\u003e For Windows: `npm i -g cross-env` and prepend the call with `cross-env` to pass environment variables, like this:\n\u003e    ```bash\n\u003e    cd /js/server\n\u003e    cross-env NODE_LANG=en...\n\u003e    ```\n\nAfterwards, call `./dev \u003cserver language\u003e` to run the server:\n\n```bash\ncd /js/server\n./dev en\n```\n\nRunning `./dev` uses the tutorial that was imported and cached by the previous command.\n\nIt does not \"watch\" tutorial text, but it reloads the server after code changes.\n\nAgain, that's for developing the server code itself, not writing the tutorial.\n\n# Troubleshooting\n\nPlease ensure you have Node.js version 10+ (`node -v` shows the version).\n\nIf it still doesn't work – [file an issue](https://github.com/javascript-tutorial/server/issues/new). Please mention OS and Node.js version.\n\nPlease pull the very latest git code and install latest NPM modules before publishing an issue.\n\n## Linux: inotify and monitored files\n\nThe server's tools use [inotify](https://en.wikipedia.org/wiki/Inotify) by default on Linux to monitor directories for changes. In some cases there may be too many items to monitor.\n\n_*!* Samples code below work correctly for Ubuntu_.\n\nYou can get your current inotify files watch limit by:\n\n```sh\n$\u003e cat /proc/sys/fs/inotify/max_user_watches\n```\n\nWhen this limit is not enough to monitor all files, you have to increase the limit for the server to work properly.\n\nYou can set a new limit temporary by:\n\n```sh\n$\u003e sudo sysctl fs.inotify.max_user_watches=524288\n$\u003e sudo sysctl -p\n```\n\nIt is very important that you refer to the documentation for your operating system to change this parameter permanently.\n\n--\u003cbr\u003eYours,\u003cbr\u003eIlya Kantor\u003cbr\u003eiliakan@javascript.info\n","funding_links":[],"categories":["others"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavascript-tutorial%2Fserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjavascript-tutorial%2Fserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavascript-tutorial%2Fserver/lists"}