React & Webpack

如果你正在做一个全新的工程,可以先阅读这篇。

否则,我们假设已经在使用Node.js和。

初始化项目结构

让我们新建一个目录。 将会命名为,但是你可以改成任何你喜欢的名字。

我们会像下面的结构组织我们的工程:

  1. proj/
  2. ├─ dist/
  3. └─ src/
  4. └─ components/

TypeScript文件会放在src文件夹里,通过TypeScript编译器编译,然后经webpack处理,最后生成一个bundle.js文件放在dist目录下。我们自定义的组件将会放在src/components文件夹下。

下面来创建基本结构:

  1. mkdir src
  2. cd src
  3. mkdir components
  4. cd ..

Webpack会帮助我们生成dist目录。

初始化工程

现在把这个目录变成npm包。

  1. npm init

你会看到一些提示,放心地使用默认值就可以了。 当然,你也可以随时到生成的package.json文件里修改。

安装依赖

首先确保已经全局安装了Webpack。

现在我们添加React和React-DOM以及它们的声明文件到package.json文件里做为依赖:

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

使用/前缀表示我们额外要获取React和React-DOM的声明文件。 通常当你导入像"react"这样的路径,它会查看react包; 然而,并不是所有的包都包含了声明文件,所以TypeScript还会查看@types/react包。 你会发现我们以后将不必在意这些。

接下来,我们要添加开发时依赖和source-map-loader

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

这些依赖会让TypeScript和webpack在一起良好地工作。 awesome-typescript-loader可以让Webpack使用TypeScript的标准配置文件tsconfig.json编译TypeScript代码。 source-map-loader使用TypeScript输出的sourcemap文件来告诉webpack何时生成_自己的_sourcemaps。 这就允许你在调试最终生成的文件时就好像在调试TypeScript源码一样。

注意我们安装TypeScript为一个开发依赖。 我们还可以使用npm link typescript来链接TypeScript到一个全局拷贝,但这不是常见用法。

添加TypeScript配置文件

我们想将TypeScript文件整合到一起 - 这包括我们写的源码和必要的声明文件。

我们需要创建一个tsconfig.json文件,它包含了输入文件列表以及编译选项。 在工程根目录下新建文件tsconfig.json文件,添加以下内容:

  1. {
  2. "compilerOptions": {
  3. "outDir": "./dist/",
  4. "sourceMap": true,
  5. "module": "commonjs",
  6. "jsx": "react"
  7. },
  8. "include": [
  9. "./src/**/*"
  10. ]
  11. }

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

写些代码

下面使用React写一段TypeScript代码。 首先,在src/components目录下创建一个名为Hello.tsx的文件,代码如下:

注意这个例子使用了无状态的功能组件,我们可以让它更像一点

  1. import * as React from "react";
  2. export interface HelloProps { compiler: string; framework: string; }
  3. // 'HelloProps' describes the shape of props.
  4. // State is never set so we use the '{}' type.
  5. export class Hello extends React.Component<HelloProps, {}> {
  6. render() {
  7. return <h1>Hello from {this.props.compiler} and {this.props.framework}!</h1>;
  8. }
  9. }
  1. import * as React from "react";
  2. import * as ReactDOM from "react-dom";
  3. ReactDOM.render(
  4. <Hello compiler="TypeScript" framework="React" />,
  5. document.getElementById("example")
  6. );

我们仅仅将Hello组件导入index.tsx。 注意,不同于或"react-dom",我们使用Hello.tsx相对路径 - 这很重要。 如果不这样做,TypeScript只会尝试在node_modules文件夹里查找。

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

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title>Hello React!</title>
  6. </head>
  7. <body>
  8. <div id="example"></div>
  9. <!-- Dependencies -->
  10. <script src="./node_modules/react/umd/react.development.js"></script>
  11. <script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
  12. <!-- Main -->
  13. <script src="./dist/bundle.js"></script>
  14. </body>
  15. </html>

需要注意一点我们是从node_modules引入的文件。 React和React-DOM的npm包里包含了独立的.js文件,你可以在页面上引入它们,这里我们为了快捷就直接引用了。 可以随意地将它们拷贝到其它目录下,或者从CDN上引用。 Facebook在CND上提供了一系列可用的React版本,你可以在这里查看。

创建一个webpack配置文件

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

大家可能对externals字段有所疑惑。 我们想要避免把所有的React都放到一个文件里,因为会增加编译时间并且浏览器还能够缓存没有发生改变的库文件。

理想情况下,我们只需要在浏览器里引入React模块,但是大部分浏览器还没有支持模块。 因此大部分代码库会把自己包裹在一个单独的全局变量内,比如:jQuery_。 这叫做“命名空间”模式,webpack也允许我们继续使用通过这种方式写的代码库。 通过我们的设置"react": "React",webpack会神奇地将所有对"react"的导入转换成从React全局变量中加载。

你可以在了解更多如何配置webpack。

整合在一起

执行:

    在浏览器里打开,工程应该已经可以用了! 你可以看到页面上显示着“Hello from TypeScript and React!”