2

I am struggling to get FileSaver to work in my project. Here is the exact step I took

  1. npm install filesaver.js --save

  2. Inside app.component.ts

import * as FileSaver from 'filesaver.js';

Then I get this error

Cannot find module 'filesaver.js'.

I also tried to add the following to my angular-cli.json file

  "scripts": [
    "../node_modules/filesaver.js/FileSaver.min.js"
  ]

This is the closest that I could find that may help. However, this guy has a different setup as me. There's got to be a simple way to use this file right?

Note, after install FileSaver from npm, inside my node-module, I get filesaver.js folder (not sure why they have .js as folder name). Inside this folder, I get FileSaver.js and FileSaver.min.js

I have also tried

import * as FileSaver from 'filesaver.js/FileSaver.min.js';

But that just gives me

Cannot find module 'filesaver.js/FileSaver.min.js'.)

----update---

I have also tried typings file for this via

npm i @types/filesaver

and the result is the same

----update-----

Here is how I got it to work.

Added @types/filesaver and added the following code.

declare module 'filesaver' {
    var saveAs: any;
    export = saveAs;
}

Note. Is it bad that I am modifying content inside my node_module file. This means that every time a user run npm install, the custom code will not be there. How to get around it?

The default folder name downloaded from npm was filesaver.js. I changed it to filesaver. Why in the world would they name it as .js, the program seems to have trouble recognizing it as a folder

then import * as filesaver from 'filesaver'

then I can call

var blob = new Blob(['Some Content'], { type: "text/csv;charset=utf-8" });
filesaver.saveAs(blob, "hello world.csv");

----- folder structure-----

angular-cli: 1.0.0-beta.26 node: 6.9.1 os: darwin x64 @angular/common: 2.4.5 @angular/compiler: 2.4.5 @angular/core: 2.4.5 @angular/forms: 2.4.5 @angular/http: 2.4.5 @angular/material: 2.0.0-beta.1 @angular/platform-browser: 2.4.5 @angular/platform-browser-dynamic: 2.4.5 @angular/router: 3.4.5 @angular/compiler-cli: 2.4.5

folder structure

user172902
  • 3,541
  • 9
  • 32
  • 75
  • You need corresponding .d.ts file in order to recognize JS file as TS module. Use existing one, i.e. https://www.npmjs.com/package/@types/filesaver – Estus Flask Feb 12 '17 at 14:48
  • Thanks for the reply. I forgot to mention that I also tried npm i @types/filesaver --save. However, it did not work. What would be the steps to get this to work with it? CHeers – user172902 Feb 12 '17 at 14:53
  • Considering that you have TS 2.0, it is usually done as you described. – Estus Flask Feb 12 '17 at 15:04
  • Would you know of a extremely popular external js library that is widely used in Angular 2. I can try importing that and see if I get any problems. That way I will know abit about what step may be the problem. There will be more information as well for it. – user172902 Feb 12 '17 at 15:19
  • Try `bluebird` and `@types/bluebird`, for example. The problem is related to TS, not to A2. – Estus Flask Feb 12 '17 at 15:32
  • When I installed @types/filesaver, does it automatically get registered somehow? Or do I have to reference it somewhere to get it going? – user172902 Feb 12 '17 at 16:04
  • Yes, `@types` packages are picked automatically in Typescript 2. See http://stackoverflow.com/questions/39261204/typings-vs-types-npm-scope . – Estus Flask Feb 12 '17 at 16:10
  • I just did a bit more research. Apprently d.ts is not required http://stackoverflow.com/questions/27417107/how-use-an-external-non-typescript-library-from-typescript-without-d-ts It seems like the problem is with the import statement. I might try another library all together – user172902 Feb 12 '17 at 16:24
  • It is required. The question you've linked states that you have to use `require` if you don't have .d.ts, you can't use `import`. The package won't get benefits of TS in this case. – Estus Flask Feb 12 '17 at 16:34

1 Answers1

0

Add to angular-cli (Which you did)

 "scripts": [
    "../node_modules/filesaver.js/FileSaver.min.js"
  ]

Then add to src/typings.d.ts

declare function saveAs(data: Blob, filename: string)

now you can use this method without any imports.

var blob = new Blob(['Some Content'], { type: "text/csv;charset=utf-8" });
saveAs(blob, "hello world.csv");

How it works.

  1. You should not create typings.d.ts, its added by angular-cli so it must be in your src folder inside of your project.
  2. When you add in angular-cli.json in section scripts then all that scripts will be loaded on page start. This is why its important that you include scripts from node_modules like you did "../node_modules/filesaver.js/FileSaver.min.js". And package was added with --save flag, as you did, so any time folders are removed and you call npm install your scripts will be on place. 3.
Vova Bilyachat
  • 18,765
  • 4
  • 55
  • 80
  • Do I create my own file typings.d.ts as it is not there at the moment? Also, how would my app component know to load it? The only d.ts files are currently inside my node_module/@types. However I dont want to add anything in there as the folder gets destroyed everytime someone do npm install. Cheers – user172902 Feb 12 '17 at 23:35
  • Thanks. Please see my updated question with the screen shot of my folder structure and angular cli version. I believe I am using quite a recent version and there is no typings.d.ts file. I have also got the code to work by modifying the d.ts file inside node_module/@types/filesaver (which I got from npm install @types/filesaver --save). However, dont like this approach due to the reason mentioned in the question. I'd like to give your approach ago if you could advise how I could ge tthis typings.d.ts to work inside src folder? Cheers – user172902 Feb 12 '17 at 23:50
  • Then add this file to src folder. – Vova Bilyachat Feb 12 '17 at 23:51
  • @user172902 btw you can call ng init and then choose n to all files its ask so it will add only new files – Vova Bilyachat Feb 12 '17 at 23:54
  • typings.d.ts file was removed by angular team for some reason https://github.com/angular/angular-cli/issues/1604 so I believe re-creating it may not be a good idea? Do you know of an alternative approach? – user172902 Feb 13 '17 at 00:01
  • Check last comment – Vova Bilyachat Feb 13 '17 at 00:02
  • @user172902 check last comment in that issue – Vova Bilyachat Feb 13 '17 at 00:07