{"componentChunkName":"component---gatsby-theme-teklog-src-templates-post-tsx","path":"/prodding-typescript/cannot-find-name-require","result":{"data":{"site":{"siteMetadata":{"siteUrl":"https://blog.tekmi.nl","author":{"name":"Teklog","avatar":"/img/tekmi-icon.svg"}}},"blogPost":{"frontmatter":{"title":"Cannot Find Name \"require\"","slug":"prodding-typescript/cannot-find-name-require","series":"prodding-typescript","date":"2020-06-12","datePretty":"12 June, 2020","coverImage":{"childImageSharp":{"fixed":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBP/EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAGDYmpsRE//xAAZEAADAQEBAAAAAAAAAAAAAAAAAQIREiH/2gAIAQEAAQUCdvcTnGhkVyeH/8QAFhEBAQEAAAAAAAAAAAAAAAAAAAER/9oACAEDAQE/AZWv/8QAGBEAAgMAAAAAAAAAAAAAAAAAAAECIVH/2gAIAQIBAT8BUtKP/8QAHBAAAgEFAQAAAAAAAAAAAAAAAAEhAhAiMTJR/9oACAEBAAY/AtmM1L06VmSj/8QAGxABAQEAAgMAAAAAAAAAAAAAAREAITFBUWH/2gAIAQEAAT8hQ7F9+MhA6eA5L5c6ZkjXvVee9//aAAwDAQACAAMAAAAQ5N//xAAXEQEBAQEAAAAAAAAAAAAAAAABAEFR/9oACAEDAQE/EOksy//EABgRAAIDAAAAAAAAAAAAAAAAAAABESHw/9oACAECAQE/ELAnkn//xAAbEAEAAwEAAwAAAAAAAAAAAAABABEhQTGBkf/aAAgBAQABPxAqPhUrhqLD01Y359yuLetmQkUfsSvWKPVzif/Z","width":1000,"height":625,"src":"/static/05c9ccd873eae55f573a808c7841926c/a7715/ProddingTypeScript_Require.jpg","srcSet":"/static/05c9ccd873eae55f573a808c7841926c/a7715/ProddingTypeScript_Require.jpg 1x"}}},"author":"Adam","authorAvatar":null},"timeToRead":5,"excerpt":"To prod I wanted to use NodeJS require directive to read a JSON file inside my TypeScript application, but... Prerequisites NodeJS Long Time Support…","html":"<h2 id=\"to-prod\" style=\"position:relative;\"><a href=\"#to-prod\" aria-label=\"to prod permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To prod</h2>\n<p>I wanted to use NodeJS <a href=\"https://nodejs.org/api/modules.html#modules_require_id\">require</a> directive to read a JSON file inside my TypeScript application, but...</p>\n<h2 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h2>\n<ul>\n<li>NodeJS Long Time Support (Version 12.x)</li>\n<li>NodeJS Package Manager (Version 6.x)</li>\n<li>TypeScript (Version 3.9.x)</li>\n<li>\n<p>The <strong>configuration.json</strong> file with the valid JSON content:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n  <span class=\"token property\">\"api_url\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"https://api.localhost\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"api_key\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"ZXH123\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n</li>\n</ul>\n<h2 id=\"tldr\" style=\"position:relative;\"><a href=\"#tldr\" aria-label=\"tldr permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>TL;DR</h2>\n<ul>\n<li>\n<p>Solution </p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i @types/node --save-dev</code></pre></div>\n</li>\n<li>Repository: <a href=\"https://github.com/tekmi/prodding-typescript/tree/master/cannot-find-name-require\">https://github.com/tekmi/prodding-typescript/tree/master/cannot-find-name-require</a></li>\n</ul>\n<h2 id=\"life-without-typescript\" style=\"position:relative;\"><a href=\"#life-without-typescript\" aria-label=\"life without typescript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Life without TypeScript</h2>\n<p>NodeJS, which uses CommonJS module format, offers a simple way to read JSON files via <code class=\"language-text\">require</code> directive; it is a synchronous operation and the file contents will be cached under <a href=\"https://nodejs.org/api/modules.html#modules_require_cache\">require.cache</a> object.\nTo demonstrate it, let's create a simple <strong>ConfigReader.js</strong> script which is going to load the <strong>configuration.json</strong> file as shown below:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> configuration <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'./configuration'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>configuration<span class=\"token punctuation\">.</span>api_url<span class=\"token punctuation\">,</span> configuration<span class=\"token punctuation\">.</span>api_key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>After executing this script with <code class=\"language-text\">node ConfigReader.js</code>, we shall see the following output <code class=\"language-javascript\">https<span class=\"token operator\">:</span><span class=\"token operator\">/</span><span class=\"token operator\">/</span>api<span class=\"token punctuation\">.</span>localhost <span class=\"token constant\">ZXH123</span></code>.\nNothing extraordinary here, yet the following things are worth noting:</p>\n<ul>\n<li><code class=\"language-text\">require</code> does not care about the file extension, as long as it is either <strong>.js</strong> or <strong>.json</strong>. However, if you created the <strong>configuration.js</strong> file with the following content <code class=\"language-javascript\">module<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> api_url<span class=\"token operator\">:</span> <span class=\"token string\">'url'</span><span class=\"token punctuation\">,</span> api_key<span class=\"token operator\">:</span> <span class=\"token string\">'key'</span> <span class=\"token punctuation\">}</span></code>, it would be loaded before the <strong>configuration.json</strong> file.</li>\n<li>if the file was not a valid JSON file, the above script would fail by raising an exception. You could catch it with <code class=\"language-text\">try-catch</code> block if needed.</li>\n<li>if you wanted to read a file in a non-blocking mode or it was not encoded in Unicode/UTF-8, then <code class=\"language-text\">fs</code> core module should be used instead.</li>\n</ul>\n<p>Until now, we have been tinkering with NodeJS and pure JavaScript. Let's switch gears and reproduce the same functionality in TypeScript.</p>\n<h2 id=\"embracing-typescript\" style=\"position:relative;\"><a href=\"#embracing-typescript\" aria-label=\"embracing typescript permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Embracing TypeScript</h2>\n<p>Let's create a simple file <strong>TypescriptConfigReader.ts</strong> with exactly the same content as before. We have to suffix it with <strong>.ts</strong> because TypeScript Compiler supports only the following extensions: <strong>.ts</strong>, <strong>.tsx</strong>, <strong>.d.ts</strong>.</p>\n<p>Confusingly enough, we could execute this file with <code class=\"language-text\">node TypescriptConfigReader.ts</code> and get the same output, without any errors. There are two reasons for it: </p>\n<ul>\n<li>First, the NodeJS Interpreter does not bother about the file extension so it can run any file that has a valid JavaScript code and uses CommonJS module format. </li>\n<li>Second, TypeScript is a superset of JavaScript and provides optional static typing, thus every valid JavaScript file is also understood by the TypeScript Compiler. By default, TypeScript is pretty permissive, but you can tighten this behavior up: for more information, please refer to <a href=\"https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html\">TypeScript Guide: Migration from JavaScript</a> </li>\n</ul>\n<p>As soon as we compile the <strong>TypescriptConfigReader.ts</strong> file with: <code class=\"language-text\">tsc TypescriptConfigReader.ts</code>, we will instantly see the following compilation error:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">TypescriptConfigReader.ts:1:23 - error TS2580: Cannot <span class=\"token function\">find</span> name <span class=\"token string\">'require'</span><span class=\"token builtin class-name\">.</span> Do you need to <span class=\"token function\">install</span> <span class=\"token builtin class-name\">type</span> definitions <span class=\"token keyword\">for</span> node? Try <span class=\"token variable\"><span class=\"token variable\">`</span><span class=\"token function\">npm</span> i @types/node<span class=\"token variable\">`</span></span><span class=\"token builtin class-name\">.</span></code></pre></div>\n<p>Strangely enough, the <strong>TypescriptConfigReader.js</strong> file has also been created and it can be run without any issues via NodeJS Interpreter. So what is going on here?</p>\n<ul>\n<li>TypeScript Compiler is special; instead of compiling your TypeScript code straight into bytecode, it compiles it to JavaScript code and nothing more. How this JavaScript code gets converted into the bytecode is the responsibility of JavaScript Runtime that lives in your browser, NodeJS, or whatever other JavaScript engines you may be using.</li>\n<li>The types you declare in your TypeScript code are used only for typechecking and they will never affect your program's generated output. This is a good thing because you can slowly introduce TypeScript into your JavaScript project without the risk of breaking it.</li>\n<li>TypeScript Compiler is pretty <a href=\"https://www.typescriptlang.org/docs/handbook/compiler-options.html#compiler-options\">configurable</a>, so you might run it like <code class=\"language-text\">tsc --noEmitOnError TypescriptConfigReader.ts</code>. In this way, no JavaScript files would be emitted if any compilation errors were reported.</li>\n</ul>\n<p>As shown above, even one line of code can make the TypeScript Compiler unhappy. Let's move on and explore the solution space together.</p>\n<h2 id=\"solution-area\" style=\"position:relative;\"><a href=\"#solution-area\" aria-label=\"solution area permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution Area</h2>\n<p>By shouting with the <em>TS2580</em> error code, the TypeScript Compiler gave us also a decent hint on how to fix it. Let's follow its advice to some extent and install the proper Type Declarations with the following command:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i @types/node --save-dev</code></pre></div>\n<p>If you run the <code class=\"language-text\">tsc TypescriptConfigReader.ts</code> now, TypeScript Compiler should not complain anymore. That was simple, but before wrapping it up, let's clarify a few things:</p>\n<ul>\n<li>If you don't have <strong>package.json</strong> file, npm command will not create one for you. Generally speaking, it is better to save every dependency in <strong>package.json</strong> file, so your coworkers have the same state of your applications as you do.</li>\n<li>If you do have the <strong>package.json</strong> file, npm command will save <code class=\"language-text\">@types/node</code> under <code class=\"language-text\">devDependencies</code>. In the end, TypeScript is a development tool and TypeScript types do not exist at runtime.</li>\n<li>You can easily find any needed <em>@types/*</em> packages on <a href=\"https://microsoft.github.io/TypeSearch\">TypeSearch</a> or <a href=\"https://www.npmjs.com/search?q=%40types\">nmpjs.com</a> </li>\n<li>You can read more about Type Declarations from <a href=\"https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html\">TypeScript Handbook</a> and check a community-maintained collection of Type Definitions for JavaScript libraries: <a href=\"https://github.com/DefinitelyTyped/DefinitelyTyped\">DefinitelyTyped</a>.</li>\n<li>If you intend to use globals (i.e.: <code class=\"language-text\">__dirname</code>, <code class=\"language-text\">__filename</code>) or any other NodeJS built-in core modules (i.e.: <code class=\"language-text\">fs</code>, <code class=\"language-text\">http</code>), you are covered. All of them are defined under the same <code class=\"language-text\">@types/node</code> Type Declarations.</li>\n</ul>"}},"pageContext":{"postId":"841a301c-2b7e-5011-86c3-ca0fcb90499e","slug":"prodding-typescript/cannot-find-name-require"}}}