webpack && React 之 Hello World

作者 糖一瓶 日期 2018-03-21
webpack && React 之 Hello World

一、MVVM框架

在说react之前,我认为有必要先简单的了解一下MVVM框架。提一嘴,建议百度进行跟深入的了解。

  • 什么是MVVM?
    • MVVM主要包括三个部分 Model View VIewModel
      • Models是数据部分对应前端js对象
      • View指的是视图部分
      • VIewModel是链接数据和试图的中间件
        数据与视图之间无法直接通讯,而是通过ViewModel进行通信
  • 说说我对MVVM框架的理解
    在我看来,无论是react还是vue或者是angular都基于这个原理。想要确认自己是否真的理解这些个框架,就问问自己是否理解数据是视图的本质,视图是数据的表现这句话。也就是说数据变化;视图就会自动变化,视图变化的原因一定是因为数据的变化,这就是MVVM框架。

二、webpack初识

webpack 做什么用的?

  • 先来整体感知一下(就看!不动手!),我现在code文件夹下有三个文件:
    test
    |- index.html
    |- main.js
    |- area.js

index.html代码如下:

    <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"    >
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script src="all.js"></script>
</body>
</html>

main.js代码如下:

import {area} from "./area.js"

alert(area(20));

area.js代码如下:

export const area = function(r) {
    return 3.14 * r * r;
}

在test文件夹下打开命令行输入命令:

webpack main.js -o all.js

这个命令执行后会生成all.js 文件 可以看到我在index.html中引入了all.js文件,打开index.html执行结果如下:
1

再看一眼all.js是个什么:
2

总结:捋一下webpack都干了些什么事:
1. 可以看到webpack从main.js出发,顺着import链儿寻找每一个js文件
2. 将顺着import找到的js文件整合打包为all.js
3. 如果我的code文件中还有个area2.js文件其中暴露了函数,但我没有在main.js中,area2.js将不会一起被打包
4. 也可以看到在all.js中去import、export化,也就是说,它是IE8兼容的。

三、webpack安装及基本使用

  1. -g 全局安装webpack和webpack-cli

    npm install -g webpack
    npm install -g webpack-cli

  2. 检查是否安装成功

    webpack -v

    4

  3. 想要webpack的工作,需要使用webpack.config.js文件来指导

    • 我们要在项目的根,创建一个webpack.config.js文件,就能指导webpack工作

        此时目录如下
        test
          |-node_modules
          |-app    
             |-main.js
             |-area.js 
          |-index.html
          |-webpack.config.js
          |-package.json
      

      webpack.config.js最基本的配置如下:

      const path = require('path');    
      module.exports = {
          entry: "./app/main.js",     //入口文件
          output: {                   //出口文件
              path: path.resolve(__dirname, "dist"),  //打包到哪个文件夹中
              filename: "bundle.js"                   //打包到哪个文件
          },
          watch : true , //实现实时监控
          mode: "development"    //要求写的,表示当前正在开发模式
      }
      
  4. 配置完成后 在命令行输入webpack命令

    webpack

    5

    • 此时就将js文件打包成了bundle.js 就相当于之前的all.js,所以index.html里script的src要改成dist/bundle.js
    • 此时就能够实时的监控文件变化,自动打包。
    • 那个自动打包的CMD不能关闭!!

四、webpack —— babel loader

webpack提供了叫做loader(加载器)的东西,可以让webpack在打包的时候顺便再进行一些其他操作。
比如babel的翻译,这个loader叫做babel-loader。接下来我们就要安装babel loader。
babel是干什么的?babel用来翻译高级语法的。

  1. 三装

    npm install --save-dev babel-core
    npm install --save-dev babel-loader
    npm install --save-dev babel-preset-env

  • babel-core:表示babel核心,
  • babel-loader表示babel的加载器
  • babel-preset-env表示babel的预处理器,让babel对ecmascript new version进行翻译。
  1. 配置webpack.config.js:

    进一步配置webpack.config.js:

    const path = require('path');
    
    module.exports = {
        entry: "./app/main.js",     //入口文件
        output: {                   //出口文件
            path: path.resolve(__dirname, "dist"),  //打包到哪个文件夹中
            filename: "bundle.js"                   //打包到哪个文件
        },
        watch : true,
        mode: "development",
        module : {
            rules: [
                {
                    test: /\.js$/,                      //以.js结尾的文件
                    include: [
                        path.resolve(__dirname, "app")  //包括什么文件夹
                    ],
                    exclude: [
                        path.resolve(__dirname, "node_modules")   //不包括
                    ],
                    loader: "babel-loader",
                    options: {
                        presets: ["env"]
                    }
                }
            ]
        }
    }
    

    6

  • module是模块的意思,表示我们需要运行哪些外置的模块,也就是说babel-loader属于外置模块。
  • rules表示规则,我们测试(test)所有以.js文件结尾的文件,include、exclude表示包括哪些文件夹、不包括哪些文件夹。
  • 使用babel-loader、选线格式presets:[“env”]
  • 再次运行webpack,此时就发现ES6的语法进行了翻译,我们的程序能够兼容到IE8了。

五、webpack-dev-server

###webpack-dev-server是做什么的?

  • 咱们先配好再告诉你
  1. -g 全局安装webpack-dev-server

    npm install -g webpack-dev-server

  2. 检查一下是否安装成功

    webpack-dev-server --version

    7

  3. 改变文件结构
  • 我们将项目的app文件夹和index.html文件放入www文件夹中,整个项目的结构:
      test
       |-node_modules
       |-www     
           |-app    
             |-main.js
             |-area.js 
           |-index.html
       |-webpack.config.js
       |-package.json
      
  1. 再次修改webpack.config.js

    修改配置webpack.config.js:

    const path = require('path');
    
    module.exports = {
        entry: "./www/app/main.js",     //入口文件
        output: {                   //出口文件
            path: path.resolve(__dirname, "www/dist"),  //打包到哪个文件夹中
            filename: "bundle.js"                   //打包到哪个文件
            publicPath : "/xuni" //虚拟文件夹
        },
        watch : true,
        mode: "development",
        module : {
            rules: [
                {
                    test: /\.js$/,                      //以.js结尾的文件
                    include: [
                        path.resolve(__dirname, "www/app")  //包括什么文件夹
                    ],
                    exclude: [
                        path.resolve(__dirname, "node_modules")   //不包括
                    ],
                    loader: "babel-loader",
                    options: {
                        presets: ["env"]
                    }
                }
            ]
        }
    }
    

    8

  2. 启动项目

    webpack-dev-server --content-base ./www --port 8080

成功界面:
9

  • content-base表示以www文件夹作为一个根目录
  • port表示端口号。
总结webpack-dev-server在干什么:
执行webpack-dev-server --content-base ./www --port 8080命令后他干了两件事:
1)在打包js文件(就是上边的webpack命令)
2)静态化www文件夹,说白了,就是说帮我们写了一个app.use(express.static("www"));
最重要的作用其实是:项目中物理磁盘上没有xuni文件夹!!但是webpack-dev-server将/xuni/bundle.js文件路由到了打包的文件,这样不会损坏硬盘!!
所以我们的index.html文件,要改变script的src为:xuni/bundle.js
  1. 配置npm run dev
    我们以后起项目输入:
    webpack-dev-server –content-base ./www –port 8080

    太长了,此时我们可以在package.json(身份证)文件中,进行配置:
    {
      "name": "test",
      "version": "1.0.0",
      "description": "",
      "main": "webpack.config.js",
      "scripts": {
          "dev" : "webpack-dev-server --content-base ./www --port 8080"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.4",
        "babel-preset-env": "^1.6.1"
      }
    }        
    
    10
  • 以后起项目,就直接使用 npm run dev

六、react 之 Hello World

  • React需要建立在webpack + babel-loader上,然后补充安装

    npm install --save react
    npm install --save react-dom
    npm install --save-dev babel-preset-react

    更改webpack.config.js

    const path = require('path');
    
    module.exports = {
        entry: "./www/app/main.js",     //入口文件
        output: {                   //出口文件
            path: path.resolve(__dirname, "www/dist"),  //打包到哪个文件夹中
            filename: "bundle.js"                   //打包到哪个文件
            publicPath : "/xuni" //虚拟文件夹
        },
        watch : true,
        mode: "development",
        module : {
            rules: [
                {
                    test: /\.js$/,                      //以.js结尾的文件
                    include: [
                        path.resolve(__dirname, "www/app")  //包括什么文件夹
                    ],
                    exclude: [
                        path.resolve(__dirname, "node_modules")   //不包括
                    ],
                    loader: "babel-loader",
                    options: {
                        presets: ["env","react"]
                    }
                }
            ]
        }
    }
    

    11

  • 接下来就开始react的起步啦!!现在我们先来删东西,出来main.js以外其他js就可以删啦。我们从头来过。
    目录结构如下:

          test
           |-node_modules
           |-www     
               |-app    
                 |-main.js
               |-index.html
           |-webpack.config.js
           |-package.json
          

    index.html里增加挂载点:

        <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0"    >
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <div id="app"></div> //增加挂载点
        <script src="all.js"></script>
    </body>
    </html>
    

    main.js代码如下:

    import React from "react";    // 引入react
    import ReactDOM from "react-dom"; // 引入react-dom
    
    ReactDOM.render(
        // jsx语法,最简单的HTML与js结合的方式,没有任何引号
        // jsx语法必须包裹在唯一的一个封闭标签中,就是最外层只能有一个标签存在不能    没有div两个h1挂在外边
        // 复制代码请删掉注释
        <div>
            <h1>你好!我是React!</h1>
            <h1>你好!我是React!</h1>
        </div>
        ,
        // 挂载到哪里,还记得index.html里我们设置的挂载点吗,注意不要在这个语句后边加分号“;”
        document.getElementById("app")
    )
    
    • react-dom这个包提供了你的app的最高等级的API,提供了元素的挂载和上树的方法。
    • Render方法接收两个参数,第二个参数是挂载点,第一个参数是react元素,用来让react元素进行挂载。
  • 运行项目:

    npm run dev
    打开8080端口可见:

    12

最简单的hello world 就跑起来了
总结一下所装的依赖(不包含-g安装的全局依赖):

"devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1"
  },
  "dependencies": {
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
  }        

react相关未完,待续……