2016-02-02 18 views
34

Tôi đã có ứng dụng Angular2 'xin chào thế giới' rất đơn giản. Tôi cũng đưa ra quyết định rõ ràng không hợp lý để làm việc với các cấu trúc thư mục khác nhau giữa dự án dev của tôi và thư mục triển khai cuối cùng trên backend mùa xuân của tôi.Nhập khẩu Angular2 & TypeScript của node_modules

Vì sự khác biệt này, tôi gặp sự cố với nhập TypeScript và dòng này đã tạo lỗi 404 (không thể tìm thấy thư viện/angular2/core) khi tôi cố gắng mở ứng dụng thực tế trong trình duyệt của mình:

import {Component, View} from 'angular2/core'; 

câu chuyện vì vậy, dài ngắn, tôi đã kết thúc cộng lại thư mục/app để làm cho công việc tất cả mọi thứ, nhưng tôi đã kết thúc sửa đổi tuyên bố nhập của tôi như sau:

import {Component, View} from '../node_modules/angular2/core'; 

này, tuy nhiên, hóa ra nguyên nhân một số hành vi kỳ lạ. Đối với một số lý do xác định ../node_modules trong các đường dẫn thư viện đang gây ra JS để thực sự tải file ALL Angular2 từ đầu sử dụng ajax gọi để lấy mỗi tập tin cá nhân từ thư mục npm_modules/angular2/ mặc dù đây là một phần của tiêu đề HTML của tôi:

<script src="/node_modules/angular2/bundles/angular2.dev.js"></script> 

Khi tôi cuối cùng đã nhận ra những gì đang xảy ra tôi hoàn nguyên câu lệnh import trở lại

import {Component, View} from 'angular2/core'; 

và tất cả làm việc. Angular2 bây giờ đã được tải hoàn toàn từ thẻ script ở trên và không có tệp nào được tải bằng các cuộc gọi ajax bổ sung.

Ai đó có thể giải thích nguyên nhân gây ra điều này không? Tôi cho rằng đó là hành vi bình thường nhưng tôi không hiểu cách thức hoạt động của quá trình nhập và lý do tại sao chỉ định đường dẫn chi tiết hơn tạo ra sự khác biệt như vậy.

+0

Để biết thêm chi tiết về cách nhập mô-đun trong thế giới TS: https://www.typescriptlang.org/docs/handbook/module-resolution.html Tài liệu được thực hiện tốt cho việc này. Có thật không. – rashadb

Trả lời

56

Các quy tắc của TypeScript tuân theo cùng quy ước như node.js. Nếu quá trình nhập bắt đầu bằng dấu chấm:

import {Something} from './some/path'; 

Sau đó, nó được coi là đường dẫn tương đối từ tệp khai báo nhập. Tuy nhiên, nếu nó là một đường dẫn tuyệt đối:

import {Component} from 'angular2/core'; 

Sau đó, nó được giả định là một mô-đun bên ngoài, vì vậy nguyên cảo sẽ đi lên cây tìm kiếm một tập tin package.json, sau đó đi vào thư mục node_modules, và tìm thấy một thư mục với cùng tên với việc nhập khẩu, sau đó trông trong package.json của các mô-đun cho chính .d.ts hay .ts tập tin, và sau đó tải rằng, hoặc sẽ tìm kiếm một tập tin có tên giống như một quy định, hoặc một index.d.ts hoặc index.ts tệp. Điều này có vẻ phức tạp khi được viết ra, và vẫn còn một số ngoại lệ ở đó ... Nhưng tất cả trong tất cả, nếu bạn đã làm việc với node.js trước đó thì điều này sẽ hoạt động chính xác theo cùng một cách.

Một điều cần lưu ý là có một trình biên dịch tùy chọn nguyên cảo rằng nên được thiết lập để gõ các nghị quyết để làm việc theo cách này

trong tsconfig.json

"moduleResolution": "node" 

Bây giờ là phần thứ hai của câu hỏi của bạn là làm sao thực hiện điều này có được nạp mà không sử dụng các cuộc gọi ajax. Đây là một tính năng của System.js. Thẻ tập lệnh được tải trong tệp index.html nhập một gói đăng ký gói angular2 với Hệ thống. Một khi điều này đã xảy ra, System biết về các tệp này và gán chúng một cách chính xác cho các tham chiếu của chúng. Đó là một chủ đề khá sâu nhưng có thể tìm thấy rất nhiều thông tin trong README của systemjs hoặc systemjs-builder.

+0

Thanks heaps cho câu trả lời chi tiết và cũng bằng văn bản. Tôi đã sử dụng nodejs tại nơi làm việc trong một vài năm nay nhưng tôi đã bằng cách nào đó quản lý để tránh chạy vào vấn đề này cho đến bây giờ. Rất vui vì bây giờ tôi biết những gì đang xảy ra đằng sau hậu trường - cảm ơn một lần nữa! – RVP

+0

@Thierry Templier: Xin chào, tôi đã sử dụng các mô-đun node.js, ví dụ: 'var fs: any = require ('fs')'. Nó gây ra vấn đề. Bạn có biết làm thế nào tôi có thể sử dụng nhập khẩu để làm điều này? –

+1

@ Ng2-Fun 'fs' là một mô-đun lõi nút sẽ không có sẵn trong trình duyệt để Systemjs sẽ không thể định vị tệp cần tải. Đây là vấn đề tôi đang gặp phải trong trường hợp sử dụng khác. Ngay cả khi chạy trong nút, Systemjs sẽ cố gắng tải một mô-đun cho điều này, mặc dù nó không cần. Tôi chưa tìm thấy một giải pháp cho điều này khác hơn là biên dịch các bản ghi để commonjs thay vào đó (mặc dù tôi đã không cố gắng chạy các ứng dụng theo cách này). Đối với các kiểu chữ không phải angular2 trong nút sử dụng commonjs, bạn có thể sử dụng 'import * as fs từ 'fs';' sẽ cung cấp cho bạn những gì bạn cần. – SnareChops

Các vấn đề liên quan