很久以前的前端,没有太多工具化工程化思想,一堆代码塞进去完事儿。如今前端已经很卷,卷到了一个开发环境都够你折腾一宿。那么我们抛开类似nextjs、create-react-app这类的工具或框架,我们该如何从零部署一个属于自己的开发环境呢?这篇文章将讲述如何配置一个基础的脚手架,支持React、TypeScrit和单元测试等必要的功能。在这个基础上,也能够很方便去个性化脚手架,让它支持比如Electron、Mobx、Redux、PM2、Express(可用来实现SSR服务端渲染)等你想要的扩展功能。
首先,我们要知道对于实际的项目,当然是效率优先,尽可能使用成熟的工具和框架,比如类似Next.js、UmiJS、Ant Design等能够简化UI Elements和脚手架环境的东西,都推荐使用它。他们能够一次性完成常用的UI架构,网站的SEO优化,服务端渲染,资源优化,性能优化(打包,懒加载等),安全优化等。对于一个项目的快速搭建和稳定性是有比较明显的作用的。这里我们学会从零部署开发环境,一方面可以利于提升自己扩展脚手架的能力,同时也能够在未来的工具和框架运用中,更加灵活的加入自己的想法。
实质上,我们现在做的事情就是搭建一个比较基础的“微前端架构(Micro-Frontend Architectures) ”,至于更加丰富的功能,可以在这个基础上不断丰富。目前某些大厂,都开源了自己的微前端架构工具,相当于也是把整个Web架构集于一体,极大提高了前后端分离、开发协作、部署测试发布迭代的整合效率,提高生产效率。萝卜各有所需,如果你的项目没有较多的约束性,可以直接使用现成的微前端架构工具,比如Bit、Piral、Modern.js等。当然如果不学习如何搭建自己的脚手架,一旦脱离了别人帮你写好的框架,你可能会显得很懵~
微前端架构其实可以很复杂,复杂到一整个大团队的协作,一个公司的业务体系,甚至不同语言开发者的分布式合作。也可以很简洁,简洁到让他成为自己的生产工具,可以用来开发,调试,可以用来部署发布,可以用来协作交流。这次写这篇文章,其实也是想抛开理论,去从某个角度去理解如何才算是自己的架构?它不一定非要打包发布,不一定非要变成一个系统的框架,微前端架构,其实和自己的生存环境,工作方式息息相关。它并不是一种标准,相当于是人定义的一种规范,一个体系。用得好了,事半功倍,用不好了,还是有不好的影响的:)
如果要真正搭建一个微前端架构,是非常复杂的,涉及的知识面很广,但是怎么去理解它的运作,从一个很小的方面去体验,就足够了。真正要使用微前端架构,还是建议引入比较成熟的架构方案,相对于中小型产品,自己瞎折腾下还是可以的。
本文分为两大部分,一个是基础配置,一个是深入配置,它将能够更好地适配你的React项目或者传统的Web项目(当然我觉得Vue也是同理的思想)。读完这篇文章,我们将实现一个由浅入深完成一套 Webpack5+TypeScript+Jest+ESLint+SASS+React
的开发环境,也可以把它当做脚手架成品。
必须: 在这之前,我们要确保你已经安装至少Node 10+ 以上的版本,我自己电脑目前的Node版本是v14.16.0。
(假设你的项目名称叫my-react-app
, 那么my-react-app
文件夹内就包含以下的目录和文件,你可以通过cd /{your_directory}/my-react-app
命令进入你的目录,使用 npm 命令安装和移除依赖项,它也会同时修改package.json
和package-lock.json
文件,具体怎么操作,相信你使用过Node的话,基本没有啥问题的)
目录如下:
下面的步骤,尽可能按照顺序来:)
(一)创建package.json文件
创建一个package.json文件,满足Webpack、TypeScript,Jest,ESLint等基本需求,同时它也满足基本的JS应用的需求。
Node 项目在项目根目录中名为 package.json 的文件中跟踪依赖关系和元数据。这是项目的核心。它包含名称、描述和版本之类的信息,以及运行、开发以及有选择地将项目发布到 npm 所需的信息。如果大家想要详细了解这个文件的用途,可以参看NPM的官方文档 https://docs.npmjs.com/creating-a-package-json-file\
关于某些Dependencies,具体的功能根据自己的需求增加,目前我主要针对我们要配置的这个环境选择,多余的依赖就不参与。
下面是已经创建好的示例代码(并非最基础的package.json代码),你可以根据需要修改它们。
{
"name": "my-react-app",
"version": "0.0.1",
"description": "My React App.",
"main": "dist/my-react-app.js",
"directories": {
"test": "test"
},
"jest": {
"testEnvironment": "jsdom",
"transform": {
"^.+\.(js|jsx)$": "babel-jest",
"^.+\.(ts|tsx)?$": "ts-jest"
}
},
"scripts": {
"check": "tsc",
"dev": "cross-env NODE_ENV=development webpack --progress --mode development --config build/config.js",
"build": "cross-env NODE_ENV=production webpack --progress --mode production --config build/config.js",
"test": "cross-env NODE_ENV=test jest"
},
"repository": {
"type": "git",
"url": "my-react-app"
},
"keywords": [
"library"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/xizon/my-react-app/issues"
},
"homepage": "https://github.com/xizon/my-react-app#readme",
"devDependencies": {
"@babel/core": "^7.13.14",
"@babel/plugin-transform-runtime": "^7.16.4",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.2.0",
"@babel/preset-typescript": "^7.1.0",
"@types/jest": "^27.0.3",
"@typescript-eslint/eslint-plugin": "^4.28.5",
"@typescript-eslint/parser": "^4.28.5",
"babel-loader": "^8.0.4",
"babel-plugin-module-resolver": "^4.1.0",
"cross-env": "^7.0.3",
"eslint": "^7.32.0",
"jest": "^27.0.4",
"jsdom": "^18.1.1",
"moment": "^2.29.1",
"terser-webpack-plugin": "^5.1.4",
"ts-jest": "^27.0.4",
"ts-node": "^10.1.0",
"typescript": "^4.3.5",
"webpack": "^5.47.1",
"webpack-cli": "^4.9.1"
},
"eslintConfig": {
"parserOptions": {
"parser": "@typescript-eslint/parser",
"ecmaVersion": 2018,
"sourceType": "module"
},
"extends": [
"plugin:@typescript-eslint/recommended"
]
},
"dependencies": {},
"author": "XXXXXXXXX"
}
(二)创建tsconfig.json文件
tsconfig.json
文件用来配置TypeScript,具体的配置选项,请阅读官方文档 https://www.typescriptlang.org/docs/handbook/tsconfig-json.html,下面是我自己的配置\
{
"compilerOptions": {
"target": "esnext",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "commonjs",
"moduleResolution": "node",
"isolatedModules": true,
"resolveJsonModule": true,
"noEmit": true,
"sourceMap": true,
"declaration": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"incremental": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": false,
"baseUrl": "./src"
},
"include": [
"src/**/*.ts"
],
"exclude": ["node_modules"]