Guide on importing a markdown file (.md) into a TypeScript project

I've been attempting to import readme files in TypeScript, but I keep encountering the error message "module not found."

Here is my TypeScript code:

import * as readme from "./README.md"; // I'm receiving an error saying module not found

I also tried adding to typings.d.ts:

declare module "*.md" {
    const value: any;
    export default value;
}

After some research, I discovered that TypeScript 2.0 introduced a feature called "Wildcard character in module names," which allows us to include any extension file.

I attempted to follow a similar example for JSON files (found at ), but unfortunately, it did not work for markdown files.

It's worth noting that I am not utilizing webpack or any loader, so I would prefer a solution solely within TypeScript.

Answer №1

If you are working with React and Typescript:

Start by creating a globals.d.ts file in the main directory (e.g. src/) with the code snippet below:

declare module "*.md";

After that, make sure to import it in this manner:

import readme from "../README.md" // Replace this path with the actual location of your README.md file

Answer №2

Using Angular 8 and TypeScript 3.5.2

To implement a custom type definition, create a file named globals.d.ts within the src folder. Remember, it must be located in the src directory for proper functionality.

declare module '*.md';

When importing in your component or service, use the following syntax:

import * as pageMarkdown from 'raw-loader!./page.md';

In the above example, page.md is situated at the same level as the component where it's being imported. This method works seamlessly with both the serve command and build --prod. If you are testing in live reload mode, ensure to restart your server to see the changes take effect.

For importing JSON files, there's a more streamlined process available. Refer to the TypeScript 2.9 Release Documentation for more information.

It's worth noting that the file does not necessarily have to be named globals.d.ts; you can choose any name you prefer, although following the convention is recommended.

Answer №3

When looking at the linked example, it's important to note that they are importing JSON, not Markdown. The reason they can import JSON successfully is because valid JSON is also considered valid JavaScript/TypeScript. Conversely, Markdown is not compatible with TypeScript, so attempting to import it in the same way will not work as expected.

If there is a need to access the Markdown file dynamically during runtime, one option is to make an AJAX request to fetch its contents. Alternatively, if embedding the Markdown directly into the JavaScript code is preferred, a build script will be necessary. While you mentioned that Webpack is not being used, it has the capability to accomplish this by creating a module rule linking "/\.md$/" with "raw-loader". A similar approach will be required using another tool.

Edit:

It appears there is always something new to discover. As pointed out by the original poster in the comments, TypeScript 2.0 now supports importing non-code resources.

To try this out, consider the following:

declare module "*!txt" {
    const content: string;
    export default content;
}

import readme from "./README.md!txt";

After implementing this setup, the variable readme should contain a string with the content of README.md.

Answer №4

In my experience, I encountered difficulties with the following setup: Vite + React + Typescript

Here's How I Solved It

I found a solution by creating a custom plugin in vite.config.ts to extract raw content from markdown files:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [
    react(),
    {
      name: "markdown-loader",
      transform(code, id) {
        if (id.slice(-3) === ".md") {
          // Extract raw content for .md files
          return `export default ${JSON.stringify(code)};`;
        }
      }
    }
  ]
});

Next Step

To ensure typescript imports markdown files correctly, add the following code to vite-env.d.ts

declare module "*.md";

Answer №5

Unfortunately, @Mitch's solution was not effective in my case. After some research, I discovered that for angular v7, a simple syntax like this did the trick:

import * as docs from 'raw-loader!./documentation.md';

Answer №6

If you are working with React and Typescript, follow these steps:

Locate the file src/react-app-env.d.ts containing the code below:

declare module "*.md";

Then import it in this manner:

import readme from "../README.md" // Adjust the path to your README.md accordingly

Answer №7

Aside from what others have suggested, it's important to include a fetch request in the process as well

Here are the overall steps that need to be followed:

Step 1: Create a file markdown.d.ts and insert the following code:

declare module '*.md' {
    const value: string; // markdown is simply a string
    export default value;
}

Step 2: Insert this code in your desired .tsx file

import data from '<path_to_md_file>.md'

useEffect(() => {
        fetch(data).then(res => res.text()).then(text => console.log(text))
}, [])

Answer №8

When working with Nx, I found a solution that avoids the need to add a file to every project or clutter my root and src folders with config files. Instead, I create a .d.ts file in a designated location and include it in the tsconfig "files" entry. Here's an example:

Create a file named config/markdown.d.ts with the following content:

declare module '*.md';

In my libs/my-lib/tsconfig.lib.json, I include the path to markdown.d.ts in the "files" array like this:

"files": ["../../config/markdown.d.ts"]

Although I still need to update the tsconfig "files" section for projects using markdown files, I find it preferable to duplicating .d.ts files across multiple locations. If you're not utilizing Nx, this may not be a concern for you.

This approach can be extended to other file extensions by creating separate .d.ts files for each extension or consolidating them into a single .d.ts file based on your requirements.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular Unit Test: Received 1 argument instead of the expected 3

Currently, I am in the process of unit testing an Angular application. This is my first time venturing into Angular Unit Testing. To save time, I downloaded the angular app from here. As a beginner in Unit Testing, I watched some informative videos on the ...

Issue in Angular Material: The export 'MaterialComponents' could not be located in './material/material.module'

I'm relatively new to Angular and I am encountering some difficulties when trying to export a material module. The error message that appears is as follows: (Failed to compile.) ./src/app/app.module.ts 17:12-30 "export 'MaterialComponents&ap ...

Retrieve validators and values from an Angular FormControl

Would you happen to know how to determine if an Angular FormControl contains a particular validator and access its value? For example, suppose I have a form control set up like this: testControl: new FormControl(null, [Validators.required, Validators.minL ...

Can you explain the distinction between needing ts-node and ts-node/register?

Currently, I am conducting end-to-end tests for an Angular application using Protractor and TypeScript. As I was setting up the environment, I came across the requirement to include: require("ts-node/register") Given my limited experience with Node.js, I ...

Encountering the error message "Receiving 'Multiple CORS header 'Access-Control-Allow-Origin' not allowed' while accessing my Laravel API from Angular"

After successfully developing an API with Laravel that functioned perfectly with Postman, I am now working on its front-end using Angular. However, I keep encountering this error every time I send a request to the API: Cross-Origin Request Blocked: The Sa ...

Error encountered in Angular NGRX while accessing the store: Trying to read property 'map' of an undefined variable

I have integrated NGRX effects into my Angular application and encountered the following error. I'm uncertain if I am using the selector correctly in my component to query the store? core.js:6162 ERROR TypeError: Cannot read property 'map' o ...

Global registration of router directives with Angular router RC3 is required

I'm trying to avoid registering the Router_Directives for each individual component. Instead, I would like to apply it globally similar to how I did before: import { RouterConfig ,Router, ActivatedRoute, ROUTE_PROVIDERS} from '@angular/router&a ...

Having Trouble Displaying Data in HTML After Making a Get Request

Upon initialization, I retrieve the data using ngOnInit() ngOnInit(): void { this.http.get<any>(this.ROOT_URL + this.cookieService.get('cookie-name')).subscribe( function(res) { this.tableData = res.atVendor; co ...

Steps for incorporating moment.js into an Angular 2 project

Having trouble importing moment.js into my angular2 application despite following various guides and solutions provided. Even though the package is present in my IDE (Visual Studio) and the moment.d.ts file is easily found, I keep encountering errors when ...

How can I adjust the indentation in Angular Prime-ng's p-tree component?

In my project, I am utilizing the primg-ng tree component for the sidebar. Currently, the output is displayed as shown here: https://i.stack.imgur.com/kcSQt.png However, I am looking to maintain consistent indentation levels without any adaptive changes ...

Angular 2: Despite changes in property, ElementRef.nativeElement.offSetwidth consistently returns the same value

Recently, I encountered an HTML element that caught my attention: <h1 [style.font-size.em]="mysize" id="title-text" #titleText>{{ screenInfo.title }}</h1> This particular element piqued my curiosity because the variable "mysize" controls the ...

Find out if a dynamically imported component has finished loading in Nextjs

Here is a simplified version of my current situation import React, { useState } from 'react'; import dynamic from 'next/dynamic'; const DynamicImportedComponent = dynamic(() => import('Foo/baz'), { ssr: false, loading ...

Error: Parsing error - Unrecognized character "@" in Angular module

Currently I am delving into the realm of webpack and attempting to integrate it into my project. However, I seem to have hit a roadblock as I encounter the following error. Despite my efforts to troubleshoot and research, I cannot seem to find a loader spe ...

Tips for transitioning from Angular 4 to Angular 5

As a newcomer to Angular, I recently launched a project using Angular CLI. However, a new version has been released since then. I am looking to update my project to the latest version of Angular (v5). How should I go about migrating it? ...

Is there a way to emphasize certain words with angular?

In order to convert all words starting with "@" into an <a> (html link) element, I am looking for a solution using Angular 8 and considering the use of a custom pipe. For example, if the phrase is "Hello, @test" -> "Hello, <a href="...&qu ...

What is causing my pug template to not display my converted Markdown correctly?

I am facing an issue with rendering HTML content retrieved from a MongoDB database using Pug. When I try to render the HTML, it duplicates the output unexpectedly... The getArticle function in viewController.js is a middleware used by routes like '/a ...

Steps for modifying the value of a field within an Angular formGroup

Is there a way to update the value of the "send_diagnostic_data" field in a separate function? private generateForm(): void { this.messageForm = new FormGroup({ message: new FormControl(''), date: new FormControl(new Date()), messag ...

Using TypeScript to assign values to object properties

In myInterfaces.ts, I have defined a class that I want to export: export class SettingsObj{ lang : string; size : number; } Now I need to reference this class in another file named myConfig.ts in order to type a property value for an object called CO ...

Using ngFor in Angular to display the API response

I am having trouble displaying a JSON response in my web panel. When attempting to show the full response, everything works perfectly. However, when I try to use ngFor, I encounter the following errors in the browser: ERROR TypeError: Cannot read property ...

What is the best way to extract the inner text from an element within a QueryList<T>?

function addGoatToVaccinationGroup(goatObject: {earTag:string, id:number}){ for (let i = 0; i < this.vaccineQueue.length; i++){ if (this.vaccineQueue[i].earTag === goatObject.earTag){ this.vaccineQueue.splice(i, 1); ...