Egg 和 Webpack 项目搭建实践

最近的项目技术栈使用 Egg + React,因为本身有 Egg,所以不希望在单独启动类似 webpack-dev-server 的工具来运行前端,而是在开发模式下,前端直接基于 Egg 运行起来。想法是好的,可是实现起来颇费了一番周折。最终的效果在 Egg-Webpack-Starter,有同样需求的朋友可以看看。下面详细讲讲配置和使用方法:

我们主要的目的是使用 Egg + Webpack 搭建一套前后端统一的开发环境,主要包括:

  • 后端 Node.js 使用 Egg 框架
  • 前端使用基于 webpack 的工作流,与具体框架无关(使用 react 做演示)
  • 开发过程中无需分别启动前端与后端应用(基于 egg-webpack)

快速使用

clone 项目

git clone https://github.com/keenwon/Egg-Webpack-Starter.git

本地开发

npm run dev

执行测试 & lint

npm test

应用部署

# 构建前端静态资源
npm run build

# 启动应用
npm start

# 停止应用
npm stop

目录结构

.
├── app                 # 服务端代码
│   ├── controller      # egg controller
│   ├── public          # 静态资源目录
│   │   └── static      # 前端 build 输出
│   └── view            # egg view
├── client              # 客户端代码
│   ├── build           # webpack config
│   └── src             # 客户端源码
│       └── views
├── config              # egg config

Egg + Webpack

详细讲述整个搭建过程,如果你只是想简单使用,直接看前面的“快速使用”就好了

Egg

首先,你得有个一 egg 应用,具体可以查看官方文档,此处不再赘述。

添加 Webpack

我们使用 egg-webpack 实现基于 egg 的 webpack 编译和热更新。关于 egg-webpack 的更多内容可以看这里

安装和配置 egg-webpack

npm install egg-webpack --save-dev

配置 egg

启用 plugin:

// 仅需 local 环境
// {root}/config/plugin.local.js

exports.webpack = {
  enable: true,
  package: "egg-webpack"
}

配置端口和 webpack config file:

// {root}/config/config.local.js

exports.webpack = {
  port: 9000,
  webpackConfigList: [require("../webpack.config")]
}

这里指定 9000 端口,后面会用到。

配置热更新

安装 webpack-hot-middleware:

npm i webpack-hot-middleware --save-dev

配置 webpack.dev.js:

module.exports = {
  // ...
  entry: {
    app: [
      // 注意端口和前面设置的一致
      "webpack-hot-middleware/client?path=http://127.0.0.1:9000/__webpack_hmr&reload=true",
      "../src/index.js"
    ]
  },
  plugins: [new webpack.HotModuleReplacementPlugin()]
  // ...
}

添加 react-hot-loader(其他框架同理):

// babel.config.js
module.exports = {
  // ...
  plugins: ["react-hot-loader/babel"]
  // ...
}

修改入口组件,使用 react-hot-loader 提供的 hoc:

import React from "react"
import {hot} from "react-hot-loader/root"

const App = () => <div>App</div>

export default hot(App)

前后端对接

这里使用 handlebar 模板,开发模式写死就好了, 生产环境读取 manifest:

{{#if isDev}}
<script type='text/javascript' src="/public/static/app.js"></script>
{{else}}
<script type='text/javascript' src="{{manifest.[runtime.js]}}"></script>
<script type='text/javascript' src="{{manifest.[vendors.js]}}"></script>
<script type='text/javascript' src="{{manifest.[app.js]}}"></script>
{{/if}} 

最后的说明

为什么 package.json 会有 acorn 相关的依赖?eslint 和其他包都可能依赖 acorn,会造成冲突,具体查看 https://github.com/eslint/espree/issues/393



标签: , ,

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

无觅相关文章插件,快速提升流量