Why do I have to use “require” instead of “import

2019-04-21 00:41发布

问题:

I see that this answer suggests the syntax for importing images as shown below (commented out). In my case, it didn't work out (complaining there's no modules to find in that file) and I had to switch to the syntax that's currently active.

// import Author from "../assets/author.png";
var Author = require("../assets/author.png");

The difference I can imagine is that I'm using TypeScript (transpiling my TSX by awesome-typescript-loader and loading my PNG file-loader) and they seem to use JSX. But as far my understanding goes, it all transpiles to plain JS and require in the end.

Being a noob on React, I'm not sure what the reason of this discrepancy is but also I'm not sure what to google for to investigate myself.

回答1:

You can declare a module for your images like this:

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

Then, you will be able to import your image like this:

import AuthorSrc from "../assets/author.png";

This is happening because webpack doesn't support image import out of the box. So you need to add a rule for that in the webpack config file. When you add a new rule, TypeScript doesn't automatically know that, so you need to declare a new module to resolve this. Without the module, you will be able to import images, but TypeScript will throw an error because you didn't tell to it is possible.



回答2:

This is more of a problem with typescript than webpack itself, you might need to declare modules on a declaration file.

Create a declarations.d.ts

Update your tsconfig.json

"include": [
    "./declarations.d.ts",
],

Put this on that file:

declare module '*.png';

Error might be gone.



回答3:

This issue has nothing to do with webpack or any bundler and is not quite a problem with typescript.

Typescript has stated that `require("path") is a way to include modules to the scope of your current module, whilst it can be also used to read some random files (such as json files, for example).

As Vincent and Playma256 specified, you can declare a module wildcard to match certain file types, so you can import it as an import statement. But you don't really need to do this. Typescript won't give you an error if you are trying to import a png or a json file (tslint might, but that depends on your configuration).

By the way, if your declaration is within the source folder of your project as defined in tsconfig.json, you don't need to include it as specified by Playma256.

I've created a sample project in node for you to test:

https://github.com/rodrigoelp/typescript-declare-files



回答4:

I think you can solve this problem with Webpack&&typescript.The official webpage of webpack has introduced something about this in https://webpack.js.org/guides/typescript/ And I have try this myself in https://github.com/reactpersopnal/webpack-root/tree/feature/typescript The reason is that you would like to use non-code assets with TypeScript, so we need to defer the type for these imports for webpack. Your could simply add custom.d.ts.

declare module "*.jpg" {
    const content: any;
    export default content;
}