React & Webpack
React&Webpack
本指南将教你如何用React和webpack连接TypeScript 。
如果您正在开始一个全新的项目,请首先查看React快速入门指南。
布置项目
让我们开始一个新的目录。我们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-loader和source-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.tsx
in 的文件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.tsx
in 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
模块,但大多数浏览器仍然不支持模块。相反,库传统上使用单个全局变量(如jQuery
or)来提供它们_
。这被称为“命名空间模式”,webpack允许我们继续利用这种方式编写库。随着我们的进入"react": "React"
,webpack将发挥它的魔力,"react"
从React
变量导入任何负载。
把它放在一起
运行:
webpack
现在打开index.html
你最喜欢的浏览器,一切都应该准备好使用!您应该看到一个页面,上面写着“来自TypeScript和React的Hello!”