当前位置: 首页 > news >正文

老旧前端项目如何升级工程化的项目

因为历史的原因存在着大量的老旧前端项目,而在今天的开发环境中已经不再适应了,于是产生了升级到新的环境的需求。比如笔者当前的一个登录页面项目,就是以下面为技术栈的老旧项目。

  • 基于 jQuery
  • 包管理基于 require.js,甚至有的没有使用全局变量
  • 没有工程化,只使用 nginx 跑起页面

问题的产生

当前旧工程乃基于 Java 工程下的子前端项目,通过 Java Maven 打包压缩混淆 js/css,如下 Maven 插件的配置。

在这里插入图片描述
其实,笔者认为通过 Java 项目整合前端工程,也是一个不错的全栈选择,其特点是前后端虽然各自开发,但在同一工程下,打包部署亦是同时一起进行的,也就是打包部署没有前后端分离,前后端一起打包部署。这一点,是自从 Servlet 3.0 发布之后 JAR 包完全具备整合相关静态资源的能力(以前的 war 包就是一个网站,当然支持静态资源混合,JAR 包则不然)。而且通过 Maven 插件实现前端构建打包,也是一个不错的思路。但通过一系列实践得出的结论是,如果是小型的前端项目,修改不多,则此法甚秒,然则比较大型的前端项目,频繁修改的话,则此法弊端渐显。因为哪怕小小的前端修改,又要跟随后端项目发包部署,时间漫长且心里压力不舒坦。

于是在后来的升级改造中,我们希望可以部署也可以前端分离。

是否改造为 MVVM 架构

jQuery 无疑是以前主流的前端库,如果贸然升级到今天的 vue/react,貌似也没有很大的必要,MVVM 固然很好而且顺手,但升级需要考虑升级后的风险,如果业务代码不通过测试则麻烦很大,抵消了升级后带来的收益。况且,新的 node/npm 工程也完全支持 jQuery 引入,只是配置上稍有不同。总之,最后决定保留 jQuery 旧有的开发模式。

升级到 node/npm 环境

今天主流前端开发离不开 node/npm,于是升级第一件事就是切换此环境。构建工具,显然还是以 webpack 为主。

JS 迁移

Require.js 使用 AMD 语法,Webpack 同样支持 AMD 语法,能够动态分析项目中的依赖项,这是项目迁移成功的关键所在。只不过 Webpack 不是直接支持,而且需要稍微配置一下。

先看一下原项目中的`requirejs.config.js``:

requirejs.config({baseUrl: '/public/js',paths: {jquery: 'lib/jquery',jqueryUI: 'lib/jquery-ui',moment: 'lib/moment',qs: 'lib/qs',lodash: 'lib/lodash',selectize: 'lib/selectize',}
});require(['jquery', 'moment', 'modal/index'], function( $, moment, modal ){console.log($);
});

对 require.js 中的配置内容映射为 webpack 中的 alias,以解决路径解析问题。让 webpack 能够解析上面path中的地址。

开始配置·webpack.config.js·中的resolve.alias

const path = require('path');
const resolve = filePath => path.resolve(process.cwd(), filePath);module.exports = {resolve: {alias: {jquery: resolve('lib/jquery'),jqueryUI: resolve('lib/jquery-ui'),moment: resolve('lib/moment'),qs: resolve('lib/qs'),lodash: resolve('lib/lodash'),selectize: resolve('lib/selectize'),}},
}

这样可以让 webpack 可以正确解析 require 的依赖。同时 require 的也可以引入不是 require 的包。

Inline js

内联 JS 是指在 html 中通过<script>置入的脚本。 这类脚本只能复制到新的一个包中,优先加载。

src js

src JS 是指在 html 中通过<scrip src=“xxx.js”>置入的脚本。 这类 JS 迁移到新的 JS 包,由 index.js/main.js 导入。

JS 压缩、混淆、source map

Webpack 构建下,打包成品是否压缩的取决于webpack.config.jsmode,设置为production即可压缩。

打开 devtool: 'source-map'生成 source map。

混淆需要 webpack-obfuscator 插件。

参考:

  • 用 webpack 替换 requirejs 打包
  • From Require.js to Webpack — Part 2 (The How)

引入 CSS

以前是<link rel="stylesheet" type="text/css" href="css/normalize.css" /> 方式引入 CSS 的,现在不用,改为在 js 包中:

import '../css/normalize.css';
import '../css/font_login/iconfont.css';

Inline CSS style 不作修改。

图片迁移

Webpack5 新特性:资源模块 ,诸如引入图片的方式可以使用 webpack5 中的资源模块,而 url-loader, file-loader, raw-loader 三个库已经不再维护。

新方式:

module: {rules: [// 图片处理{test: /\.(png|jpg|svg|jpeg|gif)$/i,type: "asset/resource",},],
},

对于需要转化成 base64 的图片,可以使用type: asset/inline

模板里面的图片

其他资源

对于其他资源文件,有需要被 XHR(Ajax)请求的资源,也可以如法炮制,关键是让 Webpack 能够识别是可控的资源,然后require()。例如 jQ 的 i18n 资源。

module: {rules: [{// i18n 资源文件test: /\.(properties)$/i,type: "asset/resource",},],},

参考:《构建webpack5.x 知识体系:3、基础之图片、html、js、其他配置》、手把手带你学webpack(3)-- Webpack中加载图片及其他资源 、webpack5资源最佳加载方案。

JS 里面的图片

例如这种,在 JS 动态引入图片url('image/index/portal_bg.jpg')

在这里插入图片描述
通过上面的 asset 配置之后,我们需要使用require()去引入图片地址。

在这里插入图片描述

HTML 里面的图片资源

HTML 里面的图片指的是<img src />引入的图片。虽然在 webpack5 中我们使用assets-module资源模块类型(asset module type)来替代比如 raw-loader 、url-loader、file-loader,但 HTML 图片不在assets-module负责之列。这是因为默认情况下,HTML 模板只是纯文本,Webpack 不能理解你想要复制在文本中引用的 asset。

这个时候需要再次增加一个 loader 配置来处理 HTML。添加 html-loader 依赖:

npm i html-loader -d

修改webpack.config.js

    module: {rules: [{ test: /.html$/, loader: 'html-loader' } // 修正 HTML 加载 img src 图片],},

然后修改图片位置,注意是相对于 HTML 文件的位置:
在这里插入图片描述

关于 base64 图片

base64 后的图片会增加体积。

不要无脑将所有图片都使用 base64 编码处理,我们使用base64编码的主要目的还是为了减少http请求
对于那些数量多,但是体积小的图片文件,如果以文件的方式打包的话会产生多条 http请求,而如果把它们全都编码成 base64 存在 js 文件中,那 http 请求只会有一次。

图片压缩插件:image-webpack-loader。

开发环境服务器

为了能够有一个良好的开发体验,我们需要在代码更新时及时看到更新后的效果,这时候就需要webpack-dev-server的帮助了。

 devServer: {static: {directory: path.resolve(__dirname, '../dist'),},watchFiles: ['public/**/*'],compress: true,port: 8000,open: false, // 是否自动打开浏览器hot: true,},

hot: true表示开启 HMR 热更新,open则表示运行webpack serve命令后自动启动浏览器打开页面。

proxy 代理配置

旧有的方式是将页面 url 与接口 url 通过本地的 Nginx 配置在同一域(Domian)下面,Nginx 反代接口,接口访问接口。如今在 Webpack 的帮助下,一切都那么自然丝滑,——它整合了一个后台服务,相当于 Ng 角色,就是代理。

devServer: {proxy: [ // 配置代理(只在本地开发有效,上线无效){context: ['/api'],target: 'http://xxxx:8100/aut',changeOrigin: true}]},

代理接口可能要多试几下,在 Postman 等工具中调通再回到开发环境中试试。

参考:1、2。


http://www.mrgr.cn/news/78328.html

相关文章:

  • 【电力行业标准】《电力信息化软件工程度量规范》(DL/T 2015-2019)-费用标准解读系列20
  • 介绍一下atof(arr);(c基础)
  • Javascript Insights: Visualizing Var, Let, And Const In 2024
  • TCP网络套接字
  • CTF之密码学(凯撒加密)
  • 可通过HTTP获取远端WWW服务信息
  • 【大模型】从零样本到少样本学习:一文读懂 Zero-shot、One-shot 和 Few-shot 的核心原理与应用!
  • 【Zookeeper】四,Zookeeper节点类型、通知、仲裁、会话
  • 去哪儿大数据面试题及参考答案
  • 使用Compose Multiplatform开发跨平台的Android调试工具
  • 小程序 - 个人简历
  • VUE练习
  • Vue学习历程一
  • 圆域函数的傅里叶变换和傅里叶逆变换
  • Jenkins的使用
  • npm库xss依赖的使用方法和vue3 中Web富文本编辑器 wangeditor 使用xss库解决 XSS 攻击的方法
  • VLLM 格式化LLM输出
  • sed
  • 1、SpringBoo中Mybatis多数据源动态切换
  • Tomcat(36)Tomcat的静态资源缓存
  • docker-compose文件的简介及使用
  • C++虚函数面试题及参考答案
  • 【vue2】封装自定义的日历组件(一)之基础的组件结构
  • Educator头歌:离散数学 - 图论
  • 【机器学习】机器学习的基本分类-监督学习(Supervised Learning)
  • Swift——自动引用计数ARC