在过去的一年和一些人中,我一直在与 Creative Tim 合作。 我一直在使用 create-react-app 来开发一些不错的产品。 有很多客户询问如何在 Webpack 上迁移我们的产品模板。
在多次要求求之后,我们写了这个关于如何开始使用 React with Webpack 4和 Babel 7 的小教程。在本教程的最后,将向大家展示如何在新创建的应用程序上添加 Material Dashboard React。
在我们开始之前,请确保你的电脑上安装了 npm 和 Nodejs 的最新版本。在撰写本文时,我的电脑上的最新版本是 npm 的 6.4.1 和 Nodejs 的 8.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()。
这将允许我们刷新页面而不会出现任何其他错误,现在我们完成了。
一个笨笨的码农,我的世界只能终身学习!
--《大迁世界》