前端 Webpack 工程化的最佳实践

作者 | 阿里文娱前端开发专家 芃苏

责编 | 屠敏

头图 | CSDN 下载自视觉中国

引言

▐ 前端构建工具的演变

回想在2015-2016年的时候,开发者们开始渐渐把视线从大量使用Task Runner的Grunt工具,转移到Gulp这种Pipeline形式的工具。Gulp还可以配合上众多个性化插件(如gulp-streamify),从而使得整个前端的准备工作链路,变得清晰易控,如刷新页面、代码的编译和压缩等等。自动化“流水线”工具取代了很多繁杂的手动工作,可以说,是具有跨时代意义的。之于Webpack而言,其本质是是基于“模块化”思想的一个“JS预编译”解决方案,诞生初期,和其相似的方案还有Browserify,和Webpack属于同门不同派别的还有sea.js或require.js,这二者需“在线依赖”解释器编译。

时至今日,多数日常工作接触的项目,已经可以完全的舍弃Gulp了。但工作中有时还会接触一些老项目,其中Gulp的使用和维护屡见不鲜。2019年初之时,通过一个老项目(gulp 3.x + webpack 3.x)的技术升级,借机了解了gulp 4.x的动态,又不禁让人回想起gulp-browserify,和gulp-webpack(五年前发布,目前改名为webpack-stream)。所以,Webpack做为某一个垂直方向的解决方案,当然可以manaually built-in Gulp中。在拿Webpack“方案”和Gulp类“工具”去做正面比较的时候,需要明晰两者解决问题的范围和思路。如今再次回顾历史,对技术的发展演变顺序,能有一个基本客观的概念。

在2017年的时候,Gulp和Webpack在用户的使用率和“将继续使用”的意向上,还不分伯仲。但从《State of Javascript 2019》 中可以看到,Webpack已经完全碾压了其它工具和类库,成为了首屈一指被大家广泛使用、讨论的Build Tool。2018年2月25日Webpack 发布了4.0.0正式版本;那是对不少项目进行了Webpack 4.10.2版本的升级;过年前后,又将部分项目升级到了4.29.0 最新版本。这一系列的“跟进式升级”中,一方面是在不断融入Webpack对于模块构建的新思路和理念,为了能够更好的适应其未来的变化(Webpack 5.x的beta版过应该不久就会面世了),另一方面是在一个好的方案中不断尝试,结合项目的基础设施优化,从而提高效能,保障产品稳定。

▐  本次回顾

Webpack工具虽说只是前端项目CI流程的一个小部分(构建 build),就它自身而言,所涉及到的Node知识和包依赖管理经验,是一整块技能。细节来看,里面涉及了Webpack自己的包和第三方plugin生态,还要配合恰当的babel、typescript、flow.js、eslint配置等多个生态,去处理Javascript语言本身的编译/转译。以及,正确管理本地静态资源文件和远端CDN资源文件路径(打包配置决定打包结果),涉及到了跨域知识和Node层服务配置、模板配置知识。更进一步还有,NPM众多包的版本管理等让人头疼的问题。其中琐碎细节数不胜数,当所有第三方工具正确使用的前提下,也许还有些plugin小工具,需要开发者去自研发。知识谱系之大,可见一斑。

本文不描述Webpack Docs使用指南,也不描述第三方插件的使用“指北”。更多的是结合过往项目经验,记录实践得出的使用技巧,也记录一些走过的弯路所带来的问题,希望对其它众多的前端技术人能够起到一点借鉴作用。 (Package Checking List:React: 16.3.2,Babel: 7.0.0,Webpack: 4.29.0,Node: 11.8.0)

文件结构

在4.x版本中的早期,CLI工具集里的命令是Webpack主包自带的,但在Webpack 4.x后期的版本,将webpack-cli作为独立包剔除出去,需要手动单独安装才可以执行tnpm run start这样的脚本命令。其次,对于开发/日常环境(dev)和预发/生产环境(prod)来说,打包的策略是截然不同的:

1. 对于dev日常环境:

  1. 方便的debug和troubleshootin,有比较强的source mapping;

  2. 希望能够得到颗粒度较小、且有根据变动代码针对性的的加载(live reloading/hot module replacement);

  3. 希望可以做一些代理Proxy相关的调试;

  4. 可以方便的根据开发者的情况,对本地的dev-server进行配置等。

2. 对于Prod生产环境:

  1. 通过压缩Javscript/CSS代码,获取更小的文件加载体积;

  2. 通过包的拆解来得到更优的加载策略,从而降低load time;

  3. 比较轻量的source mapping(当然,当你需要一些trace信息做日志和报警的时候是另外一番情景);

  4. 线上的产品的一些个性诉求(比如,对同一份Javascript代码也许要匹配不同的样式文件)等。

3. 通常评估效率维度主要有以下几个,稳重提到的数据来源主要属于前三个:

  • 本地开发compile(w/ DLL or NO DLL)

  • 本地开发re-compile(w/ DLL or NO DLL)

  • 本地测试build(webpack analyse分析的重点部分)

  • 云构建时长 (NO DLL or 配置化OSS支撑DLL)

在Webpack的新版本中,webpack-merge: 4.2.1 这个独立包的使用,开发者使用webpack.common.js文件对开发和生产环境中的公共部分进行配置,webpack.dev.js针对开发环境,webpack.prod.js针对生产环境。区分后,两种环境的配置差异,一目了然:

(图:webpack配置文件结构)

关于cz.config.js和flowGlobalVars.js里面“话题点”颇多,不在此处重点描述。

如果需要DLL配置(在后面的优化部分会重点讲),还需要单独加入一个webpack.dll.js打包的配置文件。当然,dll其实也是一个普通的文件Output,我们可以在webpack.common.js文件中module.exports时,写两个区分开。通过这种不是很常见的灵活写法(Exporting multiple configurations),可以更多的去理解文件的I/O和module模块的概念。

 

基础/自定义配置

▐  CommonsChunkPlugin被取代 

被移入到了webpack.optimization.splitChunks中。有关拆包切分和颗粒度控制,这个其实从Webpack的层面已经为我们做了很多优化,自身也是有一套基础默认的优化策略的。类比来看,React生态里面diff算法本身也是有策略机制的,更多的优化,使用者可以在这个对象里面加入回调方法,自己去细化控制。

这里需要特别注意的是cacheGroups,当不明确哪些内容需要被cache时,或者是颗粒度不好把控时,这样的切分会给我们带来非常多的冗余文件。下面的代码中,定义了一个vendors对象,那么我们的output文件(不包含chunksFiles)的每一个都会生成一个cache文件。加入output的有app.bundle.js和polyfill.bundle.js,一旦加入这个vendors对象,打包的时候会额外的生成两份文件,分别是vendors-app.js和vendors-polyfill.js。虽然不用担心这两个文件内容会重新打包代码进去,里面只是放一些cache索引,但这两个文件如果在不确定要用他们来做什么的时候,cacheGroups的设置,需要重新认真去考虑。

▐  OccurrenceOrderPlugin

本身不在是一个webpack类下面的构造器,而是被重新命名(之前的名称因为单词拼写错误了),然后放入到新的位置,调用起来需要重新去书写:new webpack.optimize.OccurrenceOrderPlugin()。

▐  terser(默认的内置压缩工具包)

webpack.optimization.minimizer的新版本中,default built-in的工具已经由旧有的uglifyJS变成了terserJS,旧的uglify已经被depreacted处理,相信不久之后的状态就会变成legacy,新的terser更好的性能,对ES6+的语法支持的更多,也同时兼容了babel 7的生态,同步其它第三方库代码压缩后的诉求。目前我在使用的是terser-webpack-plugin,和普通的terser配置的参数上有一些差异,需要自己手动引入(官方文档推荐)。

  module.rules.exclude[0]

module.rules.exclude[0]的文件地址书写,要求更加严格(4.11.0以后的版本)。

以往我们在对module.rules做配置时,有些文件不希望被遍历到,那么我们通过exclude这个参数配置,将其跳过,有时候会使用'src/contianer/xx.jsx'这样的写法,如果是多个path索引,那就放到一个Array中就好。但这种写法,在新版本中是不被允许的,我们只能使用path.resolve()或/regExp/的写法去声明文件路径地址。(Bonus Basic Tips,如何用正则书写并集和特定路径,如我希望include所有src加上一个指定的npm包: /(src\/.*)|(node_modules\/.*@ali\/lark-components)/)

▐  alias和绝对路径

webpack在打包的时候,通常需要对文件的路径去做查找、搜索,它需要明确知道文件的引用位置和引用关系,从而能够完整的知道整个映射mapping关系。减少这方面的开销,我们可以考虑去配置alias,从而以绝对路径的写法代替大量相对路径写法。好处的话,一方面是帮助webpack更快的去定位文件位置,另一方面书写起来,也不再用被输入 '../../*' 还是 '../../../*' 而困扰。

  • Webstorm寻找绝对路径:在配置里面对webpack配置项加入webpack文件路径就好,Webstorm IDE会自己找到对应的alias关系。

  • VSCode寻找绝对路径:插件层面没有发现太好的办法,如果项目正在使用typescript,可以在tsconfig.json里面配置相关的编译项,可以达到和上面Webstorm同样的效果。

▐  大图片上传CDN

上传CDN后可以大幅减小包体积。另外,webpack也不需要再去关注那些图片的文件索引路径了。项目稍微大一些,本地图片5Mb ~ 10Mb的情况非常普遍,亟待优化。

▐  devServer Proxy的代理能力

去调研这个能力,得益于一次请求层的改造。诉求是希望Token不再显示传递,而是通过塞到Header去实现。在本地开发的环境,我们通常使用jsonp去解决跨域问题,但其本质其实是在网页中嵌入一段<script />,自然也就不能写入Header信息,这个和我们的初衷并不相符,无法满足诉求。所以对于这样的跨域问题,我们通过几个简单的参数配置,在请求发起和请求返回的两端,分别做了代理配置,从而“欺骗”了“源Origin”,得以解决本地开发的跨域问题:

devServer: {
    // ...
    headers: {
      'Access-Control-Allow-Origin': '*', // CORS
    },
    proxy: { // for ajax cors
      '/h5/ajaxObj': {
        target: 'http://xxx.xxx.xxx.com',
        onProxyReq: (proxyReq) => {
          proxyReq.setHeader('Origin', 'http://xxx.xxx.com');
        },
        onProxyRes: (proxyRes) => { // …},
      },
    },
  },

优化性能 by Node / Happypack

基础配置和需要的自定义配置已经有了,整个项目的构建时间有可能还是非常不理想的,当前本文提及的测试项目,大概有57s的时间,还是有很多地方没有补足的,可优化的空间非常大。

第一步可以先关注下Node版本,经过测试,是对整体速度可以至少提升30%的事情,尤其是在Node V8版本到V10的时候,以下是之前在另一个项目做技术改造时记录到的数据:

Node版本

v 8.x

v 10.x

compile

32s - 36s

26s

re-compile

8s - 9s

4s

但是这次,在把项目直接升级到了 v 11.x 后发现,有带node-sass的项目编译构建都崩溃了。才意识到,node-sass的版本也需要相应的版本更新。也测试了Babel v 6.x 到 v 7.x 版本的升级效果,本来以为babel的大版本升级会带来显著的编译速度提高,实际上却并不理想(基本可以忽略不计)。 

打算开启多线程能力,去处理模块化打包里面那些本是单线程执行的 loaders 们的工作。Happypack的提升效率对整个项目的首次编译而言,效果是20%左右,比较明显。加入Happypack能力的时候,有两点需要注意:

  • 其对file-loader和url-loader的支持不好,可以考虑不加,毕竟我们项目里面图片类(最好上传CDN)的和非常规格式的文件只是小部分;

  • 这次也尝试了把ts-loader加入到多线程中,但是也出现了不少编译问题。大概率怀疑是我个人的配置问题,但过程中去看issues见到了不少ts-loader和ts生态依赖兼容性的问题。目前这个项目.ts只是少数文件,作为一种尝试,大部分文件还都是.jsx和.js,所以针对ts也先不加入Happypack能力了。

 

优化性能 by DLL/ Optimization

首先需要借助一些工具来进行分析,如:webpack-bundle-analyzer ,通过这个工具我们可以对整个构建(用于生产,Webpack Analyse针对的build过程,不是compile)过程和结果进行数据、图形上的分析,从而得知问题具体出现在了哪里。进而得知DLL所需拆分的内容是什么。以下内容是在第一次分析时得出的:

这个图片的 3532 modules和62 chunks可以看到具体的模块以及chunks划分后的情况。更加直观的我们来看下面这张图,可以看到Parsed的尺寸,入口文件(7.09MB)和主chunk(2.04MB,主要是一些首页就需要加载的node_module)的大小都很夸张,并且node_modules里面的包基本上是一一打包、整整齐齐:

有了这些分析结果,对应解法的思路就很清晰了:首先要抽离常用的node_modules(这是DLL的意义),然后要逐个分析,把不被经常用到的node_module们(仅被某些页面使用,不具有公共特点)也抽出去。

对于React项目中的React、React-Dom、React-router、Redux等,还要一些第三方比较大的库,比如antv或者G2相关的,也要进行DLL抽离了:

modules数量由3532降低到1500,编译时间缩短了三倍

在做了上述DLL的抽离后其实效果已经很明显了,进一步的提升空间,可以对optimization进行了配置(用法详见官方文档):

  • terser

  • chunksAll

  • no mimimizer sourceMap

结尾

本文大概主要介绍了一些工具衍变背景、基础的组织结构和自定义配置,以及如何通过分析工具去来做性能优化,其中很多小的细节没办法一一提到,比如我们看到加载的chunk都是hash值的时候,如何能够辨别是什么组件呢:解法是可以在路由处通过配置moduleName的方式去做:

() => import(/* webpackChunkName: "chunkNameDisplay" */'../containers/UserList/chunkNameDisplay')

诸如此类,实在繁多。随着Webpack 5.x版本的陆续发布和众多团队使用之后,也许很多东西又会有大的改变。并且各种框架的集成已经越来越丰富,更多的解放程序员在工程化维护上的双手,我们关注工程化的演进,看看Webpack生态会给我们带来什么样的惊喜。

【End】

《原力计划【第二季】- 学习力挑战》正式开始!
即日起至 3月21日,千万流量支持原创作者,更有专属【勋章】等你来挑战

推荐阅读 

国产 14nm 迎曙光,进口荷兰光刻机顺利入厂!

阿里华为百度三足鼎立,5G 资费高,操作系统 Linux 称王 | 中国物联网开发者真实现状报告

无需3D运动数据训练,最新人体姿势估计方法达到SOTA | CVPR 2020

年增代码 12.9 亿行,每天完成需求近 4000 个,鹅厂程序员秘密大爆料!

如何与亦敌亦友的 null 说拜拜?大神原来是这么做的!

从哈希函数、哈希冲突、开散列出发,一文告诉你哈希思想与哈希表构造到底是什么!

你点的每一个在看,我认真当成了喜欢

<div> 适用人群 <p> Java开发人员,Vue开发人员,前后端分离开发人员,权限管理和配置开发人员 </p> </div> <div> 课程概述 <div style="color:#666666;"> 【讲师介绍】<br /> 讲师职称:<br />               现某知名大型互联网公司资深架构师,技术总监,职业规划师,首席面试官,曾在某上市培训机构,高校任教多年。<br />             Array(Array老师)10多年互联网公司实战经验,知名的大型互联网公司的架构师,高管等职,在企业长期从事于技术的源码阅读和新技术的研究;擅长于职业规划,面试辅导,从事面试官多年;擅长于JAVA,人工智能AI应用,Xmind等等,曾服役于国内某上市培训机构数年,独特的培训思路,培训体系,培训方式,实践的职场技能,职场现状,职场晋升等让你快速适应企业职场的所需。 <br /> 【课程介绍】<br /> 技术选型<br /> 开发环境:Eclipse/Idea ,JDK 1.8以上 <br /> 后端技术<br /> 核心框架:SpringBoot2.x框架系列(同样适用Springcloud F版本以后的版本),如下(节选):    <br /> 持久层框架:MyBatis 3.x + Mybatis-plus 3.x<br /> 日志管理:SLF4J 1.7 + Log4j2 2.7<br /> 工具类:Apache Commons、Jackson 、fastjson、Gson<br /> 权限验证<br /> 前端技术  <br /> Vue  <br /> Vue-cli<br /> ElementUI ---https://element.eleme.io/<br /> JSX (JavaScript Xml)<br /> 前台的权限验证和路由设置<br /> 开发模式  <br />      前后端分离的开发<br /> 数据库 <br />       Mysql5<br /> IDE<br />     Intellij Idea </div> </div>
相关推荐
<p> <span>本课程从零开始,以通俗易懂的方式讲解Java技术,手把手教你掌握每一个知识点。</span> </p> <p> <span>真正做到零基础入门学习,</span><span style="color:#FF0000;">最适合初学者的教程!</span> </p> <p> <span style="color:#FF0000;"><br /></span> </p> <p> 本课程为JavaSE的阶段项目,通过<strong><span style="color:#00B050;">《购物系统》</span></strong>综合训练前面讲过的所有技术点,如:面向对象、集合、异常、IO、线程、反射、设计模式、JDBC等。 </p> <p> <br /></p> <p> <strong>项目中包含的功能:</strong> </p> <p> <span></span> </p> <p> 1.用户管理 </p> <p>     1.1 用户注册 </p> <p>          用户名不能与已存在的用户名相同 </p> <p>          要对密码进行加密处理 </p> <p>     1.2 用户登陆 </p> <p>          禁用的账户不能登陆 </p> <p>     1.3 修改密码 </p> <p>     1.4 用户注销 </p> <p> 2.商品管理 </p> <p>     2.1 商品展示 </p> <p>          支持分页显示 </p> <p> 3.购物车管理 </p> <p>     3.1 添加商品到购物车 </p> <p>     3.2 从购物车删除商品 </p> <p>     3.3 修改商品数量 </p> <p>     3.4 清空购物车 </p> <p>     3.5 查看购物车 </p> <p>     3.6 结算 </p> <p> 4.订单管理 </p> <p>     4.1 生成订单 </p> <p>     4.2 查看我的订单 </p> <p>     4.3 查看订单详情 </p> <p> <span><br /></span> </p> <p> <strong>数据库设计:</strong> </p> <p> 1. 商品表    t_product </p> <p>     id </p> <p>     name </p> <p>     price </p> <p> 2. 用户表    t_user </p> <p>     id </p> <p>     <span>username</span> </p> <p>     password </p> <p>     phone </p> <p>     address </p> <p>     status -- 状态,1表示启用,0表示禁用 </p> <p> 3. 订单表    t_order </p> <p>     id </p> <p>     user_id </p> <p>     no </p> <p>     price </p> <p>     <span>createdate</span> </p> <p> 4. 订单明细表    t_item </p> <p>     id </p> <p>     product_id </p> <p>     <span>num</span> </p> <p>     price </p> <p>     order_id </p> <p> <br /></p> <p> <br /></p> <p> <span><strong><span style="color:#FF0000;">教学全程采用笔记+代码案例的形式讲解,通俗易懂</span></strong><strong><span style="color:#FF0000;">!!!</span></strong></span> </p> <p> <img src="https://img-bss.csdn.net/201904040930441804.png" alt="" /></p> <p> <br /></p> <p> <img src="https://img-bss.csdn.net/201904040931068307.png" alt="" /></p> <p> <br /></p> <p> <img src="https://img-bss.csdn.net/201904040931162514.png" alt="" /></p> <p> <br /></p> <p> <img src="https://img-bss.csdn.net/201904040932021979.png" alt="" /></p> <p> <br /></p> <p> <img src="https://img-bss.csdn.net/201904040932114740.png" alt="" /></p> <p> <br /></p> <p> <br /></p> <p> <br /></p> <p> <strong>讲师介绍</strong> </p> <div> <strong><img src="https://img-bss.csdn.net/201904040932449689.jpg" alt="" /><br /></strong> </div>
<p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <strong><span class="md-line md-end-block" style="font-size:20px;">一、项目简介</span><span class="md-line md-end-block" style="font-size:20px;color:#ff0000;">本课程演示的<span>是一套</span><span style="background-color:#ff0000;color:#ffff00;"><strong><span class="md-line md-end-block" style="font-size:20px;">基于SSM实现的网上订餐系统</span></strong></span><strong><span class="md-line md-end-block" style="font-size:20px;"><span style="color:#333333;">,</span>主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。</span></strong></span><span class="md-line md-end-block" style="font-size:20px;color:#ff0000;"><strong><span class="md-line md-end-block" style="font-size:20px;"><br /> </span></strong><span style="font-size:18px;"><strong><span class="md-line md-end-block"><strong><span style="font-size:18px;"><strong>课程包含</strong></span></strong></span></strong><strong><span class="md-line md-end-block">:</span></strong></span></span></strong> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;">   </p> <p class="md-end-block md-p md-focus" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;"> <span style="color:#ff0000;"><strong><span style="font-size:18px;"><strong>1. <span style="background-color:#ff0000;color:#ffff00;">项目源码、项目文档、数据库脚本、软件工具</span>等所有资料</strong></span></strong></span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;"> <span style="color:#ff0000;"><strong><span style="font-size:18px;"><strong>2. 带你从零开始部署运行本套系统</strong></span></strong></span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;"> <span style="color:#ff0000;"><strong><span style="font-size:18px;"><strong>3. 该项目附带的源码资料可作为毕设使用</strong></span></strong></span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;"> <span style="color:#ff0000;"><strong><span style="font-size:18px;"><strong>4. 提供技术答疑和远程协助指导</strong></span></strong></span> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <strong><span style="font-size:20px;"><br /> 二、技术实现</span></strong> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;">   </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;"> <span class="md-plain">后台框架:Spring、SpringMVC、MyBatis</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;"> <span class="md-plain md-expand">UI界面:<span>BootStrap、H-ui 、JSP</span></span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;"> <span class="md-plain">数据库:MySQL</span> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <strong><span style="color:#494429;font-size:18px;"> </span></strong> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span style="font-size:20px;"><strong><span>三、系统功能</span></strong></span> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;">   </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;">   </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;"> <span class="md-plain">系统分为前台订餐和后台管理:</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">1.前台订餐</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">    用户注册、用户登录、我的购物车、我的订单</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">    商品列表、商品搜索、商品评论</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">2.后台管理</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">    用户管理:用户列表、用户删除、设为会员</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">    商品管理:商品列表、添加商品、修改商品、删除商品、下架商品、商品分类管理</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">    订单管理:订单列表、查看订单详细、订单发货</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">    评论管理:评论列表、评论删除</span> </p> <p class="md-end-block md-p md-focus" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span class="md-plain">    管理员管理:角色管理、权限管理、管理员列表</span> </p> <p class="md-end-block md-p" style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;font-size:16px;background-color:#ffffff;color:#333333;">   </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;">   </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span style="font-size:20px;"><strong>四、项目截图</strong></span> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span style="color:#333333;">1)<span>前台订餐</span></span> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <img src="https://img-bss.csdnimg.cn/202102050604444728.jpg" alt="" /> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;">   </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span>2)<span style="color:#333333;">后台管理</span></span> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <img src="https://img-bss.csdnimg.cn/202102050604584714.jpg" alt="" /> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;">   </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <img src="https://img-bss.csdnimg.cn/202102050605086493.jpg" alt="" /> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;">   </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span style="color:#ff0000;"><strong><span style="font-size:18px;"> </span></strong></span> </p> <p style="font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif;color:#313d54;font-size:16px;background-color:#ffffff;"> <span style="color:#ff0000;"><strong><span style="font-size:18px;">更多Java毕设项目请关注【毕设系列课程】</span></strong></span><strong><a href="https://edu.csdn.net/lecturer/2104">https://edu.csdn.net/lecturer/2104</a></strong> </p>
<p style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'PingFang SC', 'Hiragino Sans GB', Arial, 'Microsoft YaHei', Verdana, Roboto, Noto, 'Helvetica Neue', sans-serif; color: #222226; font-size: 14px; background-color: #ffffff;">微服务应用是分布式开发的主要手段,它很好的解决了高并发等电商平台的问题。微服务系列课程是以Java语言为基础,以SpringCloud+SpringBoot为核心,结合Spring、SpringMVC及MyBatis,通过游戏案例、电商案例,以极简的方式,带领入门的朋友们快速上手微服务开发。全部案例源码分享给学习的朋友,案例采用敏捷开发管理模式,让朋友们在每一个阶段,有着游戏过关一样的学习体验。</p> <p style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'PingFang SC', 'Hiragino Sans GB', Arial, 'Microsoft YaHei', Verdana, Roboto, Noto, 'Helvetica Neue', sans-serif; color: #222226; font-size: 14px; background-color: #ffffff;"> </p> <p style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'PingFang SC', 'Hiragino Sans GB', Arial, 'Microsoft YaHei', Verdana, Roboto, Noto, 'Helvetica Neue', sans-serif; color: #222226; font-size: 14px; background-color: #ffffff;">第七季主要是给大家介绍一下Java面向对象中的继承,包括:继承的概念、为什么要继承、继承的类型及特性、extends关键字、final关键字、implements关键字、super和this关键字、子类中如何调用父类中的有参、无参构造方法。</p>
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页