如何制作Webpack TypeScript React Webpack-dev-server配置以实现自动构建和重新加载页面

11

我的意图是拥有这样的目录结构:

- /my-project/
  -- /src/ (here are all .tsx files located)
  -- /dist/
     - index.html
     - /build/
        -bundle.js

 -- /node_modules/
 -- package.json
 -- tsconfig.json
 -- webpack.config.js

所以,我希望在 /dist 子目录下手动创建我的 index.html,其中包含 /build 子目录,这是 webpack 生成的 app.js 所在的位置。

当我保存一些位于 /src 目录中的 .tsx 文件时,我希望 webpack 自动重建 app.js,并且 webpack-dev-server 自动反映这些更改。

我的 package.json 如下所示:

{
  "name": "my-project",
  "version": "1.0.0",
  "description": "My first React App",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --content-base ./dist --hot --inline --colors --port 3000 --open",
    "build": "webpack --config webpack.config.js --watch",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "AndreyKo",
  "license": "ISC",
  "devDependencies": {
    "@types/react": "^0.14.54",
    "@types/react-dom": "^0.14.19",
    "jquery": "^3.1.1",
    "source-map-loader": "^0.1.5",
    "ts-loader": "^1.3.0",
    "typescript": "^2.1.4",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.2"
  },
  "dependencies": {
    "react": "^15.4.1",
    "react-dom": "^15.4.1"
  }
}

我的webpack.config.js文件:

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "app.js",
        publicPath: "/dist/",
        path: "./dist/build/"
    },
    dev_tool: "source-map",
    resolve: {
        extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js']
    },
    module: {
        loaders: [
            {test: /\.tsx?$/, loader: 'ts-loader'}
        ],
        preloaders: [
            {test: /\.js$/, loader: 'source-map-loader'}
        ]
    }
}

我的 index.html 文件:

<!DOCTYPE html>
<html>
    <body>
        <div id="app-container"></div>
    </body>
    <script src="./build/app.js"></script>
</html>

而我的 index.tsx 文件看起来像这样:

import * as jQuery from 'jquery';
import * as React from 'react';
import * as ReactDOM from 'react-dom';

function appOutput() {
    ReactDOM.render(<div>Hello, we are talking from React!</div>, document.getElementById("app-container"));
}
appOutput();

我已经在终端执行了命令:

npm run build
npm run start
所以,app.js已被创建并启动了webpack-dev-server,页面在浏览器中打开,到目前为止一切都很好。但是当我更改index.tsx文件中的文本并保存此文件时,没有任何变化。我尝试刷新浏览器页面,文本仍然保持不变,app.js也没有重新构建。为了使文本更改生效,我必须手动从终端发出“npm run build”命令重新构建app.js。
如何改进我的工作流程,以便在/src文件夹中进行的更改能够自动反映在dist/build/app.js文件中,而无需手动重新构建它?

你可能正在寻找的是热加载(hot reloading)。Dan Abramov有一个React热加载样板库应该会有所帮助。我没有找到任何好的TypeScript示例,但是我有一个正在使用它的项目,如果需要指导可以帮到你 - drewwyatt
3个回答

15

对于可能遇到react-webpack-typescript开发环境配置的任何人,我在此提供更完整且(更重要的是)更正确的答案。某种程度上,阅读文档对我来说不够好,我不得不花费一天以上的时间才能使其正常工作。

所以我想要获取打包后的JavaScript文件所在的目录结构比HTML index.html文件深一个级别。请查看初始帖子以获取完整的目录结构。

作为开发人员,当我在/src文件夹中更改一些.tsx文件时,我希望浏览器中反映出我的更改,并且我们需要重新编译打包后的.js文件。为了实现这些目的,在项目的package.json文件的scripts块中创建了两个脚本:

  "scripts": {
    "start": "webpack-dev-server --content-base ./dist --hot --inline --colors --port 3000 --open",
    "build": "webpack --config webpack.config.js --watch",
  }

第一个命令启动webpack-dev-server,为其提供根目录/dist进行服务,并使用--hot --inline参数自动重新加载浏览器页面并摆脱不必要的iframe。还有定义--port和自动打开页面的选项,当webpack-dev-server启动时。

第二个命令是通过使用--watch参数,让webpack自动重建捆绑后的app.js文件。

为了使这些命令按预期工作,webpack应该在webpack.config.js中得到正确的配置。 对我来说(以及后来发现的许多其他人),最棘手的部分是输出块的正确路径、publicPath和filename设置。我的初始帖子中publicPath的错误导致了我的webpack-dev-server无法工作。

不起作用的输出块是:

output: {
    filename: "app.js",
    publicPath: "/dist/",
    path: "./dist/build/"
}

有效的输出块如下:

output: {
    filename: "app.js",
    publicPath: "/build/",
    path: "./dist/build/"
}

publicPath属性是由webpack-dev-server用来刷新浏览器页面的,它应该设置为您编译后的.js文件所在的目录相对于根服务器目录的位置,根服务器目录由我的启动脚本中的--content-base关键字设置,指向项目内的./dist。所以正确的值是/build/而不是/dist/。

path和filename属性是由webpack和命令使用的,用来指示将打包好的.js文件放置的位置和如何命名。在我的情况下,将会创建./dist/build/app.js文件。

还有一件事情在文档中肯定存在,但我想在这里提到的是,当我在使用启动脚本启动webpack-dev-server并保存一些.tsx文件之后,但没有运行构建命令(使webpack监听更改),我可以在浏览器中得到更新的结果,但我的打包app.js文件没有被更改。这是因为webpack-dev-server仅更新打包好的.js文件的内存副本,而不是文件本身。要同步,我们需要使用webpack重新构建捆绑包。

如果我想要我的打包好的.js文件与浏览器页面保持同步,我需要让webpack监听更改并让webpack-dev-server热重载页面,因此我需要同时运行“start”和“build”脚本。 但我无法在我的Windows开发机上从一个命令提示符中运行它们两个,因此我需要分别运行每个命令:

这仅适用于Windows!

start npm run start && start npm run build

为了我的手指,我把这行代码放到了run.bat文件里,该文件放在项目文件夹中。现在我只需要在VSCode编辑器中打开Windows终端并在那里输入命令“run”。

目前就这些。


太酷了,publicPath设置搞乱了我的配置。 - Neurotransmitter
我对此感到困惑。在使用webpack-dev-server时,当我更改.tsx组件时,它会重新加载。但是实际上在浏览器中没有任何更改,即使我刷新页面,组件也没有更新。所以我发现我还需要运行webpack --watch来重新编译bundle.js。但我想知道每次我更改磁盘上的文件时,webpack-dev-server到底是如何反应的? - CMCDragonkai

1

好的,我已经成功解决了我的问题,虽然不是完美的。

由于它看起来取决于操作系统和其他环境,所以我想要更加精确: 我的操作系统 - windows7 我的编辑器 - VS Code。

首先,我想指出我的安装工作正常,没有任何调整。

但是,当我从VS Code终端运行我的构建和启动命令时,它不起作用。

为了使此工作正常,我必须打开两个单独的终端窗口,在第一个窗口中运行我的构建脚本,在第二个窗口中运行我的启动脚本:

first Terminal > npm run build
second Terminal > npm run start

在VS Code的终端中执行此操作的另一种方法是发出以下命令:
start npm run start && start npm run build 

这个命令可以完全相同 - 打开两个终端窗口并在这些窗口中运行npm命令。

最后,我创建了一个run.bat文件,在其中添加了这一行代码,现在我只需要在VS Code中打开我的项目,并在终端中运行"run"命令,webpack和webpack-dev-server开始监听更改。

就是这样。如果有更好的方法,请指出,我愿意采用更优雅的解决方案。


1

使用当前版本的webpack工具,您应该安装webpack-cli(npm install webpack-cli --save-dev),并使用以下命令:

webpack-cli serve --config ./webpack.config.js

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接