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

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

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

  • 基于 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.kler.cn/a/412296.html

相关文章:

  • 学习Java的日子 Day56 数据库连接池,Druid连接池
  • 第十六届蓝桥杯模拟赛第二期题解—Java
  • 代码美学:MATLAB制作渐变色
  • 【深度学习】利用Java DL4J构建金融欺诈检测系统
  • 5.5 W5500 TCP服务端与客户端
  • 【Redis_Day6】Hash类型
  • 鸿蒙Native使用Demo
  • ubuntu使用Docker,安装,删除,改源等记录
  • 类的加载机制
  • 自制Windows系统(十)
  • Unity 设计模式-单例模式(Singleton)详解
  • 【大数据学习 | Spark-Core】Spark中的join原理
  • 双向链表、循环链表、栈
  • Docker desktop 改变存储位置
  • VUE练习
  • Hive的基础函数
  • 英语知识在线平台:Spring Boot技术探索
  • 流媒体拥塞控制与流控
  • 几个bev模型部署常用的命令
  • 深度学习每周学习总结J6(ResNeXt-50 算法实战与解析 - 猴痘识别)
  • Spring MVC练习(前后端分离开发实例)
  • Linux -线程互斥与同步
  • qt QDateTime详解
  • 【书生大模型实战营第四期】评测 InternLM-1.8B 实践
  • LSA详情与特殊区域
  • Pydantic 数据验证