I want to use a raw-loader with my Angular 7 to import text files into my TypeScript source code. I've found plenty of information on the subject and spent a few hours trying to get it to work, but I can not get it to work.
I start by creating a new project
ng new example --defaults --minimal
I create a text file at /src/app/example.txt
with the message "Hello World"
I then modify the app.component.ts
file to import this text file.
import {Component} from '@angular/core';
import str from 'example.txt';
alert(str);
@Component({
selector: 'app-root',
template: ``,
styles: []
})
export class AppComponent {
}
I see a Cannot load module "example.txt"
error in WebStorm, and when I run ng build
and I get the following error.
ERROR in src/app/app.component.ts(2,17): error TS2307: Cannot find module 'example.txt'
So I Googled how to resolve this issue and I found this answer.
How to import JSON File into a TypeScript file?
I then add a /src/typings.d.ts
file with the following contents, and this fixes the error in WebStorm.
declare module "*.txt" {
const value: string;
export default value;
}
I run ng build
again and the error message changes to say it can't find the module.
Module not found: Error: Can't resolve 'example.txt' in 'C:\work\temp\example\src\app'
After some lengthy Googling, I figure that I need to add a raw-loader to Angular using a custom webpack configuration. Which leads me to this blog post with instructions.
https://codeburst.io/customizing-angular-cli-6-build-an-alternative-to-ng-eject-a48304cd3b21
So I install custom-webpack
npm i -D @angular-builders/custom-webpack
I edit my angular.json
so that the build uses extra-webpack.config.js
like so.
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./extra-webpack.config.js"
},
I create the extra-webpack.config.js
in the same folder as angular.json
with the following contents.
module.exports = {
module: {
rules: [
{
test: /\.txt$/,
use: 'raw-loader'
}
]
}
};
I try building again ng build
but get the same error.
Module not found: Error: Can't resolve 'example.txt' in 'C:\work\temp\example\src\app'
I have been unable to get past this point, and everything I've Googled so far seems to imply that this is how it's supposed to be done. Module not found
error messages are very broad and I can not find anything specific to Angular 7.
I figured it out, and the answer was on the raw-loader documentation page. At the bottom it explains that you have to prefix the import path with raw-loader!
https://webpack.js.org/loaders/raw-loader/#examples
import {Component} from '@angular/core';
import str from 'raw-loader!./example.txt';
alert(str);
@Component({
selector: 'app-root',
template: ``,
styles: []
})
export class AppComponent {
}
I found this very difficult to figure out. You have to figure out how to get TypeScript to recognise the modules, then you have to configure Angular to use the loader and then you have to know how to correctly import the file.
None of the Google search results showed everything together as it related to Angular 7. So I found this turns up in search results for other people.
Working in Angular 9,10 with Ivy
So I finally got it working, from this comment on an issue, here's the steps I took, if anyone else is looking for help.
yarn add -D @angular-builders/custom-webpack raw-loader
Change angular.json
to use @angular-builders/custom-webpack
...
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./webpack.partial.js"
},
...
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"browserTarget": "PROJECTNAME:build"
},
...
webpack.partial.js
next to angular.json
module.exports = {
module: {
rules: [
{ test: /\.(txt|md)$/, loader: 'raw-loader' }
]
}
};
./types/textfile.d.ts
declare module '!raw-loader!*' {
const contents: string;
export = contents;
}
tsconfig
file knows about textfile.d.ts
{
"compilerOptions": {
...
"typeRoots": ["node_modules/@types", "./types"],
... // ^ this is important
}
import { Component } from '@angular/core';
const myText = require('!raw-loader!./my-text-file.txt');
@Component({
template: `<pre>{{myText}}</pre>`,
})
export class ChangeLogComponent {
myText = myText;
}
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