Saya sedang membangun aplikasi dengan Angular 4 dan webpack.
Saya memiliki yang berikut ini di salah satu komponen saya:
ngOnInit() {
require('/assets/js/regular-expresions.js');
}
Ketika saya mencoba untuk mengkompilasi, saya mendapatkan:
ERROR di C:/SRC/Sandbox/eat-sleep-code.com/src/app/content.component.ts (21,9): Tidak dapat menemukan nama 'require'.
Saya telah menjalankan npm install @types/node --save-dev
dan memperbarui tsconfig.json saya agar terlihat seperti:
{
"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"
]
}
}
Namun sayangnya, kesalahan yang sama terus terjadi. Ada ide?
Berikut adalah package.json saya:
{
"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()
tidak disarankan karena beberapa alasan. Satu, itu akan merusak efektivitas tree-shaking di webpack 2 dan dua, itu akan mencegah pemisahan kode yang tepat.
Alternatif yang jauh lebih baik adalah dengan menggunakan implementasi webpack's dari System.import
:
System.import('/assets/js/regular-expresions.js').then(file => {
// perform additional interactions after the resource has been asynchronously fetched
});
Untuk memuaskan kompiler Typescript (seperti yang telah Anda temukan), Anda perlu memberitahukan bahwa System
adalah variabel yang dapat diterima dengan mendeklarasikannya:
declare var System: any;
Anda dapat menambahkan baris ini ke komponen Anda jika Anda hanya berniat untuk mereferensikannya sekali saja, atau Anda dapat menambahkannya ke file definisi tipe typings.d.ts
untuk memungkinkan penggunaannya di seluruh aplikasi Anda. Perhatikan bahwa jika Anda mengubah berkas typings, Anda harus memulai ulang sesi ng serve
.
Hal ini memuaskan compiler pada saat build time dan akan dibajak pada saat runtime oleh build system, menambal panggilan tersebut ke dalam Webpack's System.import
.
Webpack pada gilirannya akan memeriksa untuk melihat apakah ia memiliki potongan yang memenuhi berkas yang diminta dan, jika tidak, ia akan secara dinamis membuat tag skrip dan memasukkannya ke dalam head, memuat berkas dengan atribut async
, itulah yang terjadi dalam kasus ini.
Setelah berkas dimuat, berkas itu akan diurai dan dieksekusi. Namun, jika Anda ingin berinteraksi dengan bagian mana pun melalui callback async .then()
, berkas Anda perlu mengekspor apa pun yang ingin Anda panggil, seperti:
export function test() {
console.log('we called test');
}
Ini akan mengekspos fungsi .test()
ke callback handler Anda:
System.import('/assets/js/regular-expresions.js').then(file => {
file.test();
});