配置开发环境(webpack)以 支持 开发React

596 阅读3分钟

当我们为了一支现代的「web 应用」(全栈或前端) 准备开发环境,这个过程对于新手来说,不是特别的简单,尤其是当前端使用了像React框架的情况,因为社区生态(ecosystem)存在错综复杂的关系。这需要一些 分析,学习,和记录具体过程。

着手准备开发环境的思想准备是说,「web 应用」 开发环境的「标准」 到底是怎样的——怎样的生产效果是我们想要的,需要的,高效舒适的开发环境。还有,在技术上是一个怎样的处理过程。

什么是开发环境

我们可随意在本地文件系统中创建一个数据目录,用npm初化一个 node 包(npminit),并将VSCODE项目运行在这个目录里(npm -init),并将 VS CODE 项目运行在这个目录里(code .),已经算是准备开发环境了。当然,很明显这种环境过于原始。

首先,我们必须明白,即使准备高级的开发编辑器(IDE)也提供一定的开发舒适性,像智能提示,自动完成,甚至是提供了调试器,但是我们web 项目是 编辑器无关,它不是这里所讲的主要的开发环境配置;

另外,我们可以通用npm 为项目添加「项目源码依赖」($npm install),然而安装依赖包也不是在配置开发环境,因为源码依赖是项目功能的客观需要,不是在为开发操作提供舒适度。

通过以上二的对比,我们比较清楚认识到,在技术上,所谓「配置开发环境」,主要是指 通用npm 为项目添加「项目开发依赖」($npm install --save-dev)。至于,安装什么样的开发工具包,又怎样配置使用它们,社区则存在太多的观点和选项了。

「web 应用」 开发环境的「标准」

效果上,开发舒适性[注]是配置开发环境的价值标准。技术上,由于前端和后端的环境非常不同,「配置的任务」也非常不同,例如后端node不受浏览器影响,可以直接使用现代JS功能。

后端由于是“一”,不受用户浏览器的“多”影响,天然具备开发舒适性,所以后端项目鲜有安装大量「项目开发依赖」,最常的一项是nodemon包,提供热加载,和调试功能;前端,则主要配置webpackp 这个包

注:舒适性受主观影响,受开发者智力,水平,价值风格影响

webpack 配置过程

1 安装 项目开发依赖(webpack webpack-cli)

webpack 和一般开发依赖相似,以D安装 $ npm install webpack webpack-cli --save-dev

2 了解默认配置,以及打包概念

21 开发目录(src)和发布目录(dist)

First we'll tweak our directory structure slightly, separating the "source" code (./src) from our "distribution" code (./dist). The "source" code is the code that we'll write and edit. The "distribution" code is the minimized and optimized output of our build process that will eventually be loaded in the browser.

开发目录:我们的前端开发,全程在一个“虚拟的”环境(./src) 上开发,可以使用ESM,ES6+ JSX等; 发布目录:它是构建(build)的目标所在,是可被拷走,用作部署到生产服务器的数据

22 配置文件 webpack.config.js

const path = require('path');
module.exports = {
  entry: './src/index.js',  // 依赖入口
  output: {
    filename: 'main.js',	// 最终打包好的文件
    path: path.resolve(__dirname, 'dist'), // 发布目录
  },
};

23 前端页面 dist/index.html

这个是直接在输出目录安排的(手动静态),会有需要动态生成的前端页面,看下面

 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8" />
     <title>Getting Started</title>
   </head>
   <body>
    <script src="main.js"></script>
   </body>
 </html>

24 使用npm script执行 打包任务

package.json

 {
   "scripts": {
   "build": "webpack"
   },
   "devDependencies": {
     "webpack": "^5.4.0",
     "webpack-cli": "^4.2.0"
   }
 }

3 主页面的“打包” 插件:html-webpack-plugin

上面的 23 中 index.html 是手动的 在大一点项目中,index.html 也会作为“源码模块”,需要动态打包

31 安装 html-webpack-plugin

npm i html-webpack-plugin --save-dev

32 在源码目录创建 index “模块”,并配置webpack

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

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src", "index.html")
    })
  ]
};
//// index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>React with Webpack</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

4 安装 webpack专用开发服务器

webpack-dev-server doesn’t write any output files after compiling. Instead, it keeps bundle files in memory and serves them as if they were real files mounted at the server’s root path.

webpack-dev-server 编译后不写入任何输出文件。 相反,它将捆绑文件保存在内存中,并将它们视为安装在服务器根路径上的真实文件。

41 webpack-dev-server

$ npm install webpack-dev-server --save-dev

42 package.json

update our dev script, in package.json, to use the server:

"dev": "webpack serve --mode development"

43 webpack.config.js

in webpack.config.js by adding the following property after the output:

devServer: {
  contentBase: './deploy',
  open: true
},

Error: ENOSPC: System limit for number of file watchers reached, watch'所在文件路径' 解决方案

在终端按顺序执行下面两个命令即可解决问题

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p sudo sysctl --system

5 配置 清理任务

出口目录(output)不会被webpack跟踪的,所以随项目进展,可能会有“垃圾”,所以最好在每一次构建前先清理目录

51

npm install clean-webpack-plugin --save-dev

52

webpack.config.js:

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

...

plugins: [ ... new CleanWebpackPlugin() ],

6 配置 支持 ES6+

开始使用 loader,对「web 模块进行预处理」,这里第一个,当然是生出 ESM 模块——将ES6+的模块转译为ES5模块。

61 安装 babel 核心以及转译插件

$ npm i @babel/core babel-loader @babel/preset-env --save-dev

62 配置babel支持ES6+ 转译

configure babel by creating a new file, babel.config.json

{
  "presets": [
    "@babel/preset-env"
  ]
}

63 配置 webpack 使用 babel loader

configure webpack to use the loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,	// 
        exclude: /node_modules/,
        use: ["babel-loader"]
      }
    ]
  },
  plugins: []
};

7 配置支持 JSX

支持 JSX 和支持ES6 的性质很类似(另一个babel 插件),JSX可以看和ES6一样,是一种高级语法,需要转换。只是转换 React 特定的ES5模块。

71 安装 babel 插件

babel 核心前面已经安装了,这里只需安装 react 插件

$ npm i @babel/preset-react --save-dev

72 配置babel支持JSX 转译

configure babel to use the React preset in babel.config.json:

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

8 配置支持 CSS

将 JS以外的web 资源进行模块化需要一点点解释。样式,和图片等“web 模块”,与JS模块处理是不同,所以使用独立的loader (JS模块预处理使用babel);另外,这些模块的预处理,和打包操作也是JS模块不同。例如:CSS模块使用 css-loader预处理为web模块,再用 style-loader进行“打包”。 css-loader parses the CSS into JavaScript and resolves any dependencies style-loader outputs our CSS into a tag in the HTML document. 如果使用scss,那么处理CSS WEB模块前,还有一些预处理,使用 sass-loader 。

81 安装 loader

$ npm i css-loader style-loader --save-dev

82 配置 loader

注意loader顺序敏感,反向从右到左,要先预处理,再打包

 configure them in webpack.config.js:
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      }
    ]
  },

参考