使用 webpack 4 和 Babel 7 构建 React 应用及如何引入 Material Design

129 阅读12分钟
原文链接: mp.weixin.qq.com

在过去的一年和一些人中,我一直在与 Creative Tim 合作。 我一直在使用 create-react-app 来开发一些不错的产品。 有很多客户询问如何在 Webpack 上迁移我们的产品模板。

在多次要求求之后,我们写了这个关于如何开始使用 React with Webpack 4和 Babel 7 的小教程。在本教程的最后,将向大家展示如何在新创建的应用程序上添加 Material Dashboard React。

在我们开始之前,请确保你的电脑上安装了 npm Nodejs 的最新版本。在撰写本文时,我的电脑上的最新版本是 npm6.4.1 和 Nodejs8.12.0 (lts)

建立项目

首先,创建工程目录:

    mkdir react-webpack-babel-tutorial

    cd react-webpack-babel-tutorial

现在我们已经创建了我们要开发应用程序的文件夹,接着需要添加一个 package.json 文件。 有两种创建方式,你可以选择其中的一种:

1.只需创建 package.json 文件,无需任何其他配置:

    npm init -y

如下所示,package.json 文件已创建,其中包含一些非常基本的信息。

2.使用一些额外的配置设置创建 package.json 文件

    npm init

我在我们新创建的 package.json 文件中添加了一些东西,比如一些很好的 keywords,一个r epo 等等...

之后,在根目录下创建 src 文件夹,然后在 src 下分别创建 `index.html 和 index.js.

1.Linux / MacOS 命令

    mkdir src

    touch src/index.html

    touch src/index.js

2.Windows 命令

    mkdir src

    echo "" > src\index.html

    echo "" > src\index.js

创建完后在 index.html 添加以下内容。

接着在 index.js 中添加一些内容,目前只是为了展示一些内容,下面继续完善。

    (function () {

      console.log("hey mister");

    }());

此时,目录结构如下:

将 Webpack 添加到项目中

安装 Webapck 及所需的开发环境依赖模块。

    npm install --save-dev webpack webpack-cli webpack-dev-server

webpack

 - 用来配置我们的新应用

 - 本文所用的版本是 4.19.0

webpack-cli

 - 可以在命令行中使用 Webpack 了

 - 本文所用的版本是 3.1.0

webpack-dev-server

 - 这样,当我们对新应用程序中的文件进行更改时,就不需要刷新页面了。每当我们在应用程序中更改文件时,它会自动刷新浏览器页面

 - 本文所用的版本是 3.1.8

看一下 package.json 文件,将看到这三个包被添加到这个文件中,如下所示:

补充说明一下版本号前的 ^,~ 的区别

1. 指定版本:比如"webpack": "4.19.0",表示安装 4.19.0 的版本

2. 波浪号 ~ 指定版本:比如 "webpack-cl": "~3.1.0",表示安装 3.1.0 的最新版本(不低于1.1.0),但是不安装 1.2.x,也就是说安装时不改变大版本号和次要版本号

3. ^ 指定版本:比如 "webpack-dev-server": "^3.1.8",,表示安装 `请输入代码 3.1.4 及以上的版本,但是不安装4.0.0,也就是说安装时不改变大版本号。 

 package.json 文件只能锁定大版本,也就是版本号的第一位,并不能锁定后面的小版本,你每次 npm install 都是拉取的该大版本下的最新的版本,为了稳定性考虑我们几乎是不敢随意升级依赖包的,这将导致多出来很多工作量,测试/适配等,所以 package-lock.json 文件出来了,当你每次安装一个依赖的时候就锁定在你安装的这个版本。

所以当我们 npm install 安装完插件后,都会生成两个文件一个是 node_modules package-lock.json 。

这里为了版本的一致性,我把 package.json 里的 版本号前面 ^ 删除了。

接着新建 Webpack 配置文件 webpack.config.js

1.Linux/MacOS 命令

    touch webpack.config.js

2.Windows  命令

    echo "" > webpack.config.js

如果你不想使用命令行,也可以简单地手动创建文件。

在开始处理 Webpack 配置文件之前,先在应用程序中安装一些我们需要的东西。

首先安装 path 作为开发环境的路径依赖。

    npm install --save-dev path

此外,由于不想在 HTML 中手动注入 index.js 文件,因此需要安装 html-webpack-plugin 的插件。 此插件通过配置在 HTML 文件中注入 index.js,无需手动操作。

    npm install --save-dev html-webpack-plugin

再次,我将 package.json 文件删除所有 ^

安装完后在  package.json 文件中的 scripts 属性里添加以为内容:

    "webpack": "webpack",

    "start": "webpack-dev-server --open"

现在 package.json 内容如下:

接着运行以下命令,看看会发生什么:

    npm run webpack

Webpack 将自动获取 src/index.js 文件,编译它,并将其输出到 dist/main.js 中,并压缩代码。这是因为我们还没有配置 Webpack 配置文件。此外,由于我们还没有配置该文件,我控制台中将出现一些警告。

如果我们运行如下命令:

    npm start

webpack-dev-server 将自动启动服务器并使用该服务器打开默认浏览器。但是,由于我们没有配置 webpack.config.js 文件,所以页面展示并不是我们想要的内容。

如果想停止服务,只需在命令行中同时按下 CTRL + C 键。

接着在 webpack.config.js 添加以下内容:

   

1.entry

entry 可以是个字符串或数组或者是对象。 当 entry 是个字符串的时候,用来定义入口文件:

  entry: './js/main.js'

当 entry 是个数组的时候,里面同样包含入口js文件,另外一个参数可以是用来配置webpack提供的一个静态资源服务器,webpack-dev-server。webpack-dev-server 会监控项目中每一个文件的变化,实时的进行构建,并且自动刷新页面:

    entry: [

         'webpack/hot/only-dev-server',

         './js/app.js'

    ]

当 entry 是个对象的时候,我们可以将不同的文件构建成不同的文件,按需使用,比如在我的 hello 页面中只要 \ 引入 hello.js 即可:

     entry: {

         hello: './js/hello.js',

         form: './js/form.js'

     }

2.output 

output 参数是个对象,用于定义构建后的文件的输出。其中包含 path 和 filename:

    output: {

         path: './build',

         filename: 'bundle.js'

     }

3.mode

这是输出的模式,这里将其 mode 设置为 “development”。如果在脚本中指定 NODE_ENV 变量,那么它将使用这个变量。请参阅下面关于如何使用 NODE_ENV 的示例(请注意,本教程中的 package.json 文件中不会进行以下更改,这只是一个示例,可以看到它是如何工作的)

"webpack": "NODE_ENV=production webpack",

#### 4.resolve 

**webpack** 在构建包的时候会按目录的进行文件的查找,**resolve** 属性中的 `extensions` 数组中用于配置程序可以自行补全哪些文件后缀:

    resolve:{

      extensions:['','.js','.json']

    }

5.devServer

这告诉 webpack-dev-server 需要提供哪些文件。 这里是 src 文件夹中的所有内容都需要在浏览器中浏览。

6.plugins

在这里,我们设置了我们的应用程序中需要的插件。到目前为止,只需要 html-webpack-plugin,它告诉服务器 index.bundl.js 应该被注入到 index.html 文件中

再次运行以下命令,显示会跟上一次不同:

    npm run webpack

webpack-dev-server 从 src 文件夹中读取所有内容并输出到我们的浏览器中。

配置 React,Babel 与 styles loaders 

通过运行以下命令来引入 React :

    npm i react react-dom --save-dev

在我们的开发过程中,如果我们在 JS 文件中添加React代码,Webpack 会给我们一个错误,它不知道如何在 bundle.js 文件中编译 React

修改 index.js 内容如下:

再次运行以下命令:

    npm start

错误如下:

所以这就是 Babel 出现的原因, Babel 将告诉 Webpack 如何编译 React 代码。

安装 Babel 相关依赖:

@babel/core

这是将ES6及以上版本编译成ES5

@babel/node

babel-node 是 babel-cli 的一部分,它不需要单独安装。

它的作用是在 node 环境中,直接运行 es2015 的代码,而不需要额外进行转码。例如我们有一个 js 文件以 es2015 的语法进行编写(如使用了箭头函数)。我们可以直接使用 babel-node es2015.js 进行执行,而不用再进行转码了。

可以说:babel-node = babel-polyfill + babel-register

@babel/preset-react

这个是把 React 代码编译成 ES5 代码。

babel-loader

babel-cli 一样,babel-loader 也会读取 .babelrc 或者 package.json 中的 babel 段作为自己的配置,之后的内核处理也是相同。唯一比 babel-cli 复杂的是,它需要和 webpack 交互,因此需要在 webpack 这边进行配置。比较常见的如下:

如果想在这里传入 babel 的配置项,也可以把改成:

我们需要为项目中添加一些样式,此时就需要使用样式相关的加载器,这边使用 `scss`,安装命令如下:

    npm install --save-dev style-loader css-loader sass-loader node-sass

style-loader

通过注入 <style> 标签将 CSS 添加到 **DOM** 中

css-loader

css-loader 用于将 css 文件打包到js中, 常常配合 style-loader 一起使用,将 css 文件打包并插入到页面中

sass-loader

加载 SASS/SCSS 文件

node-sass

SCSS 文件编译为 CSS 文件

src 下创建 scss 文件:

1.Linux/MacOS 命令

    touch src/index.scss

2.window 命令

    echo "" > src/index.scss

并添加以下内容:

接着导入 index.js 中

    

记得删除 package.json 中的 ^ 号,内容如下:

   

如果我们再次运行上述任何命令,错误仍将存在。 我们还没有告诉 Webpack 它应该使用 Babel 和样式加载器来编译我们的 React 和 SCSS 代码。

接下来要做的是为 Babel 添加配置文件。 为此,需要创建一个名为 .babelrc 的文件,用来配置 Babel

可以直接在 webpack.config.js 文件中添加 Babel 的配置。 为此,你可以查看官方的 babel-loader 文档。 就我而言,我认为最好将 Babel 配置放在自己的文件中,这样就不会使 Webpack 配置过于复杂难读。

在根目录下创建 .babelrc

1.Linux/MacOS 命令

    touch .babelrc

2.Windows 命令

    echo "" > .babelrc

并在 .babelrc 中添加以下代码,这样 babel-loader 就会知道用什么来编译代码:

    {

      "presets": [

        "@babel/env",

        "@babel/react"

      ]

    }

完成这些步骤后,我们需要在项目中添加一些内容,以便我们可以导入各种文件,如图像。 还需要添加一个插件,让我们可以使用类等等。 让我们在类中添加类属性,基本上,它将让我们能够使用 面向对象编程 方式来编写代码。

因此,让我们将 webpack.config.js 更改为以下内容(我也添加了一些注释,可能会对你有所帮助):

我们需要对 package.json 文件做一个更改。我们需要告诉我们的脚本在 Webpack 的配置文件中,使用 import 而不是 require 语句。 否则它会给我们一个错误,它不知道 import 表示什么。

我们还需要在 .babelrc 文件中添加 @babel/plugin-proposal-class 属性,Babel 将会知道如何处理类属性。

现在总算配置完成了。再次运行上述任何一个命令,就可以顺利跑起来啦。

    npm run webpack

    npm start

使用 Webpack 和 Babel 项目将 Material Design 加到我们的新 React 项目中

正如在这篇文章的开头讲的,我们不会讲  Material Design 样式如何写,这需要大量的工作。

相反,这里添加一个很好的产品来实现 Google 的 Material Design,其中包括[Creative Tim][31] 员工的一些小改动。 我们将向其添加 Material Dashboard React

首先从 github 上把项目拷贝下来:

好的,现在我们有两个项目 -  Material Dashboard React 和 我们刚创建的项目。

现在,我们不能简单地将 src 文件夹从 Material Dashboard React 复制到我们的新项目中。 这会给我们带来很多错误, 如缺少依赖关系的错误,找不到模块等。

因此,我建议首先将 Material Dashboard React 的 package.json 中的依赖项添加到 package.json 中。 我们不需要 Material Dashboard React 包中的所有依赖项,因为我们使用 Webpack 构建了自己的服务器。 除了产品本身,我们还添加了其他样式加载器。

所以说,我们需要如下:

我们不会全部都讲,你可以在 [npmjs.com][35] 上找到它们的详细信息和它们自己的文档。

再一次,进入 package.json 文件并从我们刚刚安装的安装包中删除(^)

 

接着拷贝 Material Dashboard React  src 下的所有文件到我们项目 src 下

  

好了,差不多做完了,我们拷贝 Material Dashboard React 下的 src 文件中所有内容到我们项目 src 下,并覆盖 index.js 文件。但是要保留 index.html 文件。

拷贝前

拷贝后

现在需要在 index.html 中添加一些样式和字体,如下:

    

还有一个小问题。 当我们刷新页面时,有一个错误 Cannot GET/dashboard。 如果我们跳转到另一个页面,会得到如, Cannot GET /user 错误等 。 所以根本上,我们的路由不起作用,需要在 src/index.js 或 webpack.config.js 中进行一些更改。

这里选择使用第一个方案,因为它非常简单易懂。

我们在新导航方式在 index.js 更改 history,使用 createHashHistory() 替换 createBrowserHistory()

这将允许我们刷新页面而不会出现任何其他错误,现在我们完成了。

   

一个笨笨的码农,我的世界只能终身学习!

--《大迁世界》