I am building an app with Angular 4 and webpack.
I have the following in one of my components:
ngOnInit() { require('/assets/js/regular-expresions.js'); }
When I attempt to compile, I get:
ERROR in C:/SRC/Sandbox/eat-sleep-code.com/src/app/content.component.ts (21,9): Cannot find name 'require'.
I have ran npm install @types/node --save-dev
and updated my tsconfig.json to look like:
{ "compileOnSave": false, "compilerOptions": { "outDir": "./dist/out-tsc", "baseUrl": "src", "sourceMap": true, "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es5", "types": [ "node" ], "typeRoots": [ "node_modules/@types" ], "lib": [ "es2016", "dom" ] } }
But alas, the same error keeps getting thrown. Any ideas?
Here is my package.json:
{ "name": "eat-sleep-code.com", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular/animations": "^4.0.1", "@angular/common": "^4.0.0", "@angular/compiler": "^4.0.0", "@angular/core": "^4.0.0", "@angular/forms": "^4.0.0", "@angular/http": "^4.0.0", "@angular/material": "^2.0.0-beta.3", "@angular/platform-browser": "^4.0.0", "@angular/platform-browser-dynamic": "^4.0.0", "@angular/router": "^4.0.0", "@types/node": "^6.0.69", "angularfire2": "^2.0.0-beta.8", "core-js": "^2.4.1", "firebase": "^3.7.8", "jquery": "^3.2.1", "jquery-validation": "^1.16.0", "ng2-gist": "^1.0.0", "promise-polyfill": "^6.0.2", "requirejs": "^2.3.3", "rxjs": "^5.1.0", "typescript": "^2.2.2", "web-animations-js": "^2.2.4", "webpack": "^2.4.1", "zone.js": "^0.8.4" }, "devDependencies": { "@angular/cli": "1.0.0", "@angular/compiler-cli": "^4.0.0", "@types/jasmine": "2.5.38", "@types/node": "^6.0.69", "codelyzer": "~2.0.0", "jasmine-core": "~2.5.2", "jasmine-spec-reporter": "~3.2.0", "karma": "~1.4.1", "karma-chrome-launcher": "~2.0.0", "karma-cli": "~1.0.1", "karma-coverage-istanbul-reporter": "^0.2.0", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.1.0", "ts-node": "~2.0.0", "tslint": "~4.5.0", "typescript": "^2.2.2", "webpack": "^2.4.1" } }
require() is internal to NodeJS and not available to users of Angular CLI if I am not mistaken. I cannot use this code as it fails.
To solve the "Cannot find module path or its corresponding type declarations" error, install the types for node by running the command npm i -D @types/node . You can then import path with the following line of code import * as path from 'path' .
Try adding declare var require: any;
on top.
require()
is not advisable for a few reasons. One, it will "break" the effectiveness of tree-shaking in webpack 2 and two, it will prevent proper code splitting.
A far better alternative is to use webpack's implementation of System.import
:
System.import('/assets/js/regular-expresions.js').then(file => { // perform additional interactions after the resource has been asynchronously fetched });
In order to satisfy the Typescript compiler (as you have found), you will need to tell it that System
is an acceptable variable by declaring it:
declare var System: any;
You can either add this line to your component if you only intend to reference it once, or you can add it to the typings.d.ts
type definition file to enable its use throughout your app. Note that if you change the typings file, you will need to restart the ng serve
session.
This satisfies the compiler at build time and it gets hijacked at runtime by the build system, patching the call through into Webpack's System.import
.
Webpack in turn will check to see if it has a chunk that satisfy the requested file and, if it does not, it will dynamically create a script tag and insert it into the head, loading the file with the async
attribute, which is what occurs in this case.
Once the file loads, it will be parsed and executed. However, if you want to interact with any part of it via the async .then()
callback, your file will need to export anything you wish to invoke, such as:
export function test() { console.log('we called test'); }
This will expose the .test()
function to your callback handler:
System.import('/assets/js/regular-expresions.js').then(file => { file.test(); });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With