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

server/2024/11/27 10:15:18/

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

  • 基于 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.ppmy.cn/server/145310.html

相关文章

Error: Invalid version flag: if 问题排查

问题描述&#xff1a; 国产化系统适配&#xff0c;arm架构的centos 在上面运行docker 启动后需要安装数据库 依赖perl 在yum install -y perl 时提示&#xff1a; “Error: Invalid version flag: if”

MYSQL表的增删改查(下)

目录 修改&#xff08;Update&#xff09; 删除&#xff08;Delete&#xff09; 本文主要介绍的是表的修改的删除&#xff0c;如果需要了解新增和查询的可以看&#xff1a;MYSQL 表的增删改查&#xff08;上&#xff09;-CSDN博客 修改&#xff08;Update&#xff09; 语法…

环状DNA序列的最小表示法

问题描述 环状 DNA 又称超螺旋&#xff0c;即一段碱基序列呈现环状&#xff0c;在分析时&#xff0c;需要将相同序列的环状 DNA 分到相同组内&#xff0c;现需将环状碱基序列按照最小表示法进行排序。 一段长度为 n 的碱基序列&#xff0c;按照顺时针方向&#xff0c;碱基序列…

代码随想录算法训练营第十三天(递归遍历;迭代遍历;统一迭代;层序遍历)

递归遍历 LeetCode 144. 二叉树的前序遍历 题目链接&#xff1a;二叉树的前序遍历题目链接 代码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) …

基于Java Springboot餐饮美食分享平台

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA 数据库&#xff1a;MySQL8.0 …

Django 路由层

1. 路由基础概念 URLconf (URL 配置)&#xff1a;Django 的路由系统是基于 urls.py 文件定义的。路径匹配&#xff1a;通过模式匹配 URL&#xff0c;并将请求传递给对应的视图处理函数。命名路由&#xff1a;每个路由可以定义一个名称&#xff0c;用于反向解析。 2. 基本路由配…

Python人工智能项目报告

一、实践概述 1、实践计划和目的 在现代社会&#xff0c;计算机技术已成为支撑社会发展的核心力量&#xff0c;渗透到生活的各个领域&#xff0c;应关注人类福祉&#xff0c;确保自己的工作成果能够造福社会&#xff0c;同时维护安全、健康的自然环境&#xff0c;设计出具有包…

计算机网络习题解答--个人笔记(未完)

本篇文章为关于《计算机网络-自顶向下方法第七版》的阅读总结和课后习题解答(未完待续) 第二章&#xff1a; cookie&#xff1a;&#xff08;这里是比较老版本的HTTP&#xff0c;具体HTTPs是怎么实现的不是很清楚&#xff09;cookie的原理其实很简单。就是在HTTP消息头上又多…