React & Webpack

React&Webpack

本指南将教你如何用Reactwebpack连接TypeScript 。

如果您正在开始一个全新的项目,请首先查看React快速入门指南

否则,我们假设你已经在使用Node.js的NPM

布置项目

让我们开始一个新的目录。我们proj现在就为它命名,但你可以将它改为任何你想要的。

mkdir proj cd proj

首先,我们将按照以下方式构建我们的项目:

proj/ ├─ dist/ └─ src/ └─ components/

TypeScript文件将从您的src文件夹开始,运行于TypeScript编译器,然后运行webpack,最后放入一个bundle.js文件中dist。我们编写的任何组件都将进入该src/components文件夹。

让我们支撑这一点:

mkdir src cd src mkdir components cd ..

Webpack将最终dist为我们生成目录。

初始化该项目

现在我们将把这个文件夹变成一个npm包。

npm init

你会得到一系列提示。您可以使用除入口点之外的默认值。您可以随时返回并在package.json为您生成的文件中进行更改。

安装我们的依赖关系

首先确保全球安装Webpack。

npm install -g webpack

Webpack是一个将代码和可选的所有依赖项捆绑到一个.js文件中的工具。

现在让我们将React和React-DOM以及它们的声明文件作为依赖项添加到您的package.json文件中:

npm install --save react react-dom @types/react @types/react-dom

@types/前缀意味着我们也想获取React和React-DOM的声明文件。通常,当你导入一个路径时"react",它会看到react包内部; 然而,并非所有的软件包都包含声明文件,所以TypeScript也会在@types/react软件包中查找。你会看到我们以后甚至不需要考虑这个问题。

接下来,我们将在awesome-typescript-loadersource-map-loader中添加开发时依赖项。

npm install --save-dev typescript awesome-typescript-loader source-map-loader

这两个依赖关系都会让TypeScript和webpack在一起很好地发挥作用。awesome-typescript-loader帮助Webpack使用TypeScript的标准配置文件命名来编译TypeScript代码tsconfig.json。source-map-loader使用TypeScript的任何源映射输出在生成自己的源映射时通知webpack。这将允许您调试最终的输出文件,就好像您在调试原始的TypeScript源代码一样。

请注意,awesome-typescript-loader不是打字机的唯一装载程序。你可以改用ts-loader。在这里了解它们之间的差异

请注意,我们将TypeScript安装为开发依赖项。我们也可以通过将TypeScript链接到全局副本npm link typescript,但这不太常见。

添加一个TypeScript配置文件

你会想把你的TypeScript文件放在一起 - 你将要写的代码以及任何必要的声明文件。

为此,您需要创建一个tsconfig.json包含输入文件列表以及所有编译设置的列表。只需在您的项目根目录中创建一个新文件,tsconfig.json并填入以下内容:

{ "compilerOptions": { "outDir": "./dist/", "sourceMap": true, "noImplicitAny": true, "module": "commonjs", "target": "es5", "jsx": "react" }, "include": [ "./src/**/*" ] }

你可以tsconfig.json在这里了解更多关于文件

写一些代码

让我们用React编写我们的第一个TypeScript文件。首先,创建一个名为Hello.tsxin 的文件src/components并写入以下内容:

import * as React from "react"; export interface HelloProps { compiler: string; framework: string; } export const Hello = (props: HelloProps) => <h1>Hello from {props.compiler} and {props.framework}!</h1>;

请注意,虽然此示例使用无状态功能组件,但我们也可以让我们的示例稍微有点

import * as React from "react"; export interface HelloProps { compiler: string; framework: string; } // 'HelloProps' describes the shape of props. // State is never set so we use the '{}' type. export class Hello extends React.Component<HelloProps, {}> { render() { return <h1>Hello from {this.props.compiler} and {this.props.framework}!</h1>; } }

接下来,让我们用以下来源创建一个index.tsxin src

import * as React from "react"; import * as ReactDOM from "react-dom"; import { Hello } from "./components/Hello"; ReactDOM.render( <Hello compiler="TypeScript" framework="React" />, document.getElementById("example")

我们刚刚导入我们的Hello组件index.tsx。请注意,不像"react"或者"react-dom",我们使用相对路径Hello.tsx-这是很重要的。如果我们没有,TypeScript会试着看我们的node_modules文件夹。

我们还需要一个页面来显示我们的Hello组件。在创建的根文件proj命名index.html,其内容如下:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> </head> <body> <div id="example"></div> <!-- Dependencies --> <script src="./node_modules/react/umd/react.development.js"></script> <script src="./node_modules/react-dom/umd/react-dom.development.js"></script> <!-- Main --> <script src="./dist/bundle.js"></script> </body> </html>

请注意,我们包含来自内部的文件node_modules。React和React-DOM的npm软件包包括.js可以包含在网页中的独立文件,我们直接引用它们可以让事情变得更快。随意将这些文件复制到另一个目录,或者将它们托管在内容交付网络(CDN)上。Facebook使得React的CDN托管版本可用,您可以在这里阅读更多信息。

创建一个webpack配置文件

在项目目录的根目录下创建一个webpack.config.js文件。

module.exports = { entry: "./src/index.tsx", output: { filename: "bundle.js", path: __dirname + "/dist" }, // Enable sourcemaps for debugging webpack's output. devtool: "source-map", resolve: { // Add '.ts' and '.tsx' as resolvable extensions. extensions: [".ts", ".tsx", ".js", ".json"] }, module: { rules: [ // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'. { test: /\.tsx?$/, loader: "awesome-typescript-loader" }, // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. { enforce: "pre", test: /\.js$/, loader: "source-map-loader" } ] }, // When importing a module whose path matches one of the following, just // assume a corresponding global variable exists and use that instead. // This is important because it allows us to avoid bundling all of our // dependencies, which allows browsers to cache those libraries between builds. externals: { "react": "React", "react-dom": "ReactDOM" }, };

你可能想知道这个externals领域。我们希望避免将所有React捆绑到同一个文件中,因为这会增加编译时间,而且如果库不更改,浏览器通常能够缓存库。

理想情况下,我们只需从浏览器中导入React模块,但大多数浏览器仍然不支持模块。相反,库传统上使用单个全局变量(如jQueryor)来提供它们_。这被称为“命名空间模式”,webpack允许我们继续利用这种方式编写库。随着我们的进入"react": "React",webpack将发挥它的魔力,"react"React变量导入任何负载。

您可以在这里了解更多关于配置webpack的信息

把它放在一起

运行:

webpack

现在打开index.html你最喜欢的浏览器,一切都应该准备好使用!您应该看到一个页面,上面写着“来自TypeScript和React的Hello!”