《React+Redux前端开发实战》—1.5.3 Hello World进阶

举报
华章计算机 发表于 2019/07/24 23:28:28 2019/07/24
【摘要】 本节书摘来自华章计算机《React+Redux前端开发实战》一书中的第1章,第1.5.3节,作者是徐顺发.

1.5.3  Hello World进阶

  前面使用Webpack实现了最简单的项目构建,每次写完代码都需要手动刷新浏览器来查看实时效果。接下来继续完善上面的构建项目,实现如下功能:

  •  项目启动,开启HTTP服务,自动打开浏览器;

  •  实时监听代码变化,浏览器实时更新;

  •  生产环境代码构建。

  模块热替换(Hot Module Replacement,HMR)是Webpack中最令人兴奋的特性之一。当项目中的代码有修改并保存后,Webpack能实时将代码重新打包,并将新的包同步到浏览器,让浏览器立即自动刷新。

  在开始配置前,读者可以先思考一个问题,如何实现浏览器实时更新呢?也许会想到让浏览器每隔一段时间向本地服务器发送请求,采用轮询(Polling)方式来实现;或者让服务器端来通知客户端,服务器端接收到客户端有资源需要更新,就主动通知客户端;或者直接使用WebSocket?

说明:WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC6455,并由RFC7936补充规范。

WebSocket API也被W3C定为标准。WebSocket使客户端和服务器端之间的数据交换变得更加简单,允许服务器端主动向客户端推送数据。以上信息参考来源于维基百科。

  其实HMR原理就是上面说的那样,早期HMR的原理是借助于EventSource,后来使用了WebSocket。可以在本地开发环境开启一个服务,将其作为本地项目的服务端,然后与本地浏览器之间进行通信即可。欲了解详情,请读者自行学习。

注意:WebSocket是基于TCP的全双工通信协议。

  大致了解了HMR的原理之后,开始动手实践吧。

  实时更新的Hello World示例:

  (1)首先,采用webpack-dev-server作为HMR的工具。在之前的项目基础上安装:

  

  npm install webpack-dev-server –D

  

  (2)修改webpack.config.js文件:

  

  + devServer: {

  +    port: 3000,

  +    contentBase: "./dist"

  + },

  

  devServer.port是服务启动后的端口号,devServer.contentBase是配置当前服务读取文件的目录。启动后可以通过localhost:3000端口访问当前项目。

  (3)修改package.json文件:

  

    "scripts": {

  +   "start": "webpack-dev-server --open --mode development",

      "test": "echo \"Error: no test specified\" && exit 1"

    },

  

  按照上面配置start命令后,执行npm start会直接找到webpack.config.js来启动项目。

  (4)最后安装html-webpack-plugin和clean-webpack-plugin。

  

  npm install html-webpack-plugin clean-webpack-plugin -D

  

  html-webpack-plugin插件用于简化创建HTML文件,它会在body中用script标签来包含我们生成的所有bundles文件。配置如下:

  

    plugins: [

      new HtmlWebpackPlugin({

        template: "index.html",

        // favicon: 'favicon.ico',

        inject: true,

        sourceMap: true,

        chunksSortMode: "dependency"

  })

    ]

  

  clean-webpack-plugin插件在生产环境中编译文件时,会先删除build或dist目录文件,然后生成新的文件。

  (5)随着文件的增、删,打包的dist文件内可能会产生一些不再需要的静态资源,我们并不希望将这些静态资源部署到服务器上占用空间,所以最好在每次打包前清理dist目录。在Webpack中配置如下:

    plugins: [

      new CleanWebpackPlugin(["dist"])

    ]

  

  此时,Webpack代码清单如下:

  

  var webpack = require("webpack");

  var path = require("path");

  const CleanWebpackPlugin = require("clean-webpack-plugin");

  var BUILD_DIR = path.resolve(__dirname, "dist");     // 输出路径

  var APP_DIR = path.resolve(__dirname, "src");         // 项目路径

  const HtmlWebpackPlugin = require("html-webpack-plugin");

  var config = {

    entry: APP_DIR + "/index.jsx",                             // 项目入口

    output: {

      path: BUILD_DIR,                                                   // 输出路由

      filename: "bundle.js"                                              // 输出文件命名

    },

    module: {

      rules: [

        {

          test: /\.(js|jsx)$/,           // 编译后缀为js和jsx的格式文件

          exclude: /node_modules/,

          use: {

            loader: "babel-loader"

          }

        }

      ]

    },

    devServer: {                                  // 在开发模式下,提供虚拟服务器用于项目开发和调试

      port: 3000,                                                                  // 端口号

      contentBase: "./dist"

    },

    plugins: [                                                                  // 拓展Webpack功能

      new HtmlWebpackPlugin({                                           // 生成HTML文件

        template: "index.html",

        // favicon: 'theme/img/favicon.ico',

        inject: true,

        sourceMap: true,                                                       // 是否生成sourceMap

        chunksSortMode: "dependency"

      }),

      new CleanWebpackPlugin(["dist"])                         // 清除文件

    ]

  };

  module.exports = config;

  

  (6)在根目录终端执行npm run start:

  

  AllandeMacBook-Pro:react-hello-world jack$ npm start

  > myfirstapp@1.0.0 start /Users/allan/react-hello-world

  > webpack-dev-server --open --mode development

  // 删除dis文件

  clean-webpack-plugin: /Users/alan/react-hello-world/dist has been removed.

   wds: Project is running at http://localhost:3000/

   wds: webpack output is served from /

   wds: Content not from webpack is served from ./dist

   wdm: wait until bundle finished: /

   wdm: Hash: 4bfc0734100357258e1f

  Version: webpack 4.23.1

  Time: 1358ms

  Built at: 2018-11-06 20:11:12

    Asset    Size Chunks       Chunk Names

  bundle.js  1.12 MiB  main [emitted] main

  index.html 342 bytes     [emitted]

  Entrypoint main = bundle.js

  [0] multi ./node_modules/_webpack-dev-server@3.1.10@webpack-dev-server/ clienthttp://localhost:3000 ./src/index.jsx 40 bytes {main} [built]

  [./node_modules/_ansi-html@0.0.7@ansi-html/index.js] 4.16 KiB {main} [built]

  [./node_modules/_ansi-regex@2.1.1@ansi-regex/index.js] 135 bytes {main} [built]

  [./node_modules/_events@1.1.1@events/events.js] 8.13 KiB {main} [built]

  [./node_modules/_loglevel@1.6.1@loglevel/lib/loglevel.js] 7.68 KiB {main} [built]

  [./node_modules/_react-dom@16.6.0@react-dom/index.js] 1.33 KiB {main} [built]

  [./node_modules/_react@16.6.0@react/index.js] 190 bytes {main} [built]

  [./node_modules/_strip-ansi@3.0.1@strip-ansi/index.js] 161 bytes {main} [built]

  [./node_modules/_url@0.11.0@url/url.js] 22.8 KiB {main} [built]

  [./node_modules/_webpack-dev-server@3.1.10@webpack-dev-server/client/index.jshttp://localhost:3000] ./node_modules/_webpack-dev-server@3.1.10@webpack-dev-server/clienthttp://localhost:3000 7.78 KiB {main} [built]

  [./node_modules/_webpack-dev-server@3.1.10@webpack-dev-server/client/overlay.js] 3.58 KiB {main} [built]

  [./node_modules/_webpack-dev-server@3.1.10@webpack-dev-server/client/socket.js] 1.05 KiB {main} [built]

  [./node_modules/_webpack@4.23.1@webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built]

  [./node_modules/webpack/hot sync ^\.\/log$] ./node_modules/webpack/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]

  [./src/index.jsx] 2.22 KiB {main} [built]

    + 22 hidden modules

  Child html-webpack-plugin for "index.html":

    1 asset

    Entrypoint undefined = index.html

    [./node_modules/_html-webpack-plugin@3.2.0@html-webpack-plugin/lib/loader.js!./index.html] 506 bytes {0} [built]

    [./node_modules/_lodash@4.17.11@lodash/lodash.js] 527 KiB {0} [built]

    [./node_modules/_webpack@4.23.1@webpack/buildin/global.js] (webpack)/ buildin/global.js 489 bytes {0} [built]

    [./node_modules/_webpack@4.23.1@webpack/buildin/module.js] (webpack)/ buildin/module.js 497 bytes {0} [built]

   wdm: Compiled successfully.

  

  此时,一旦项目内的文件有改动,就会自动执行编译,并通知浏览器自动刷新。

  (7)至此开发配置已经完成,接下来配置生产命令,只需执行webpack-p即可。webpack -p表示压缩打包代码。在package.json内配置:

  

    "scripts": {

      "start": "webpack-dev-server --open --mode development",

  +   "build": "webpack -p",

      "test": "echo \"Error: no test specified\" && exit 1"

    },

  

  (8)打包的时候只需执行npm run build即可,打包成功会出现:

  

  AllandeMacBook-Pro:react-hello-world allan$ npm run build

  > myfirstapp@1.0.0 build /Users/allan/react-hello-world

  > webpack -p

  clean-webpack-plugin: /Users/allan/react-hello-world/dist has been removed.

  Hash: 97bb34a13d3fc8cbfccc

  Version: webpack 4.23.1

  Time: 2647ms

  Built at: 2018-11-06 20:22:45

    Asset    Size Chunks       Chunk Names

  bundle.js  110 KiB    0 [emitted] main

  index.html 342 bytes     [emitted]

  Entrypoint main = bundle.js

  [2] ./src/index.jsx 2.22 KiB {0} [built]

    + 7 hidden modules

  Child html-webpack-plugin for "index.html":

    1 asset

    Entrypoint undefined = index.html

    [0] ./node_modules/_html-webpack-plugin@3.2.0@html-webpack-plugin/lib/loader.js!./index.html 506 bytes {0} [built]

    [2] (webpack)/buildin/global.js 489 bytes {0} [built]

    [3] (webpack)/buildin/module.js 497 bytes {0} [built]

      + 1 hidden module

  

  上面的打包结果展示了此次打包的哈希值、耗时,以及打包后每个包的大小等信息。此时项目的结构为:

  

  .

  ├──  README.md

  ├──  dist

  │      ├──  bundle.js

  │      └──  index.html

  ├──  index.html

  ├──  package-lock.json

  ├──  package.json

  ├──  src

  │      └──  index.jsx

  └──  webpack.config.js

  

  以上项目的完整代码可以在https://github.com/khno/react-hello-world中下载,分支为dev。本书中后面章节的代码案例默认将以此为基础运行,读者可以自行下载。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。