动态import来拆分代码后发布问题

本文探讨了在单页应用(SPA)中,如何通过动态import和hash值解决发布后资源路径不一致的问题,避免404错误,同时介绍了解决方案包括设置HTML不缓存、给动态引入的JS加上hash值以及设置缓存头信息。

当使用SPA(单页应用)的时候,为了提高性能,我们经常使用动态import来拆分代码。这种情况发布的时候可能会有这样的问题:

假如用户在发布前已经进入该应用,当用户在发布后再进入某个引入分片代码的的界面,那么很可能页面静态资源的路径是旧的,而服务器新发布的资源路径是新的(大多数路径不一样是文件名的hash值不同导致的,我们这里也假设是这样情况),那么两个路径不一样,从而导致404的发生。

我们这里讲一种简单的处理方法:

  1. 设置HTML不缓存
<meta http-equiv="Cache" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
  1. 给动态引入的JS加上hash值,这一块不懂的可以看这篇文章
//动态import处代码
import(/* webpackChunkName: "[request]" */`../../containers/${requestPath}`)
//webpack.config.js
//... 其他代码
output: {
    //... 其他代码
    filename: '[name].[hash].js',
    chunkFilename: '[name].[hash].js',//这里使用hash,也可以是其他的hash具体按自己的项目来定
},
//... 其他代码
  1. 设置缓存头信息
//我这里使用的是koa2做为服务器的 根据使用的服务器来设置响应头信息就可以了
app.use(require('koa-static')(__dirname + '/public',{
    maxage:1209600000//这个时间根据具体的项目来自己定
}))

通过上述步骤就可以了,当用户在发布后再进入某个引入分片代码的的界面,那么页面中的引用是旧的资源路径,由于页面有缓存那么不会报错。当用户新进入页面的时候(比如刷新一下)那么由于HTML文件是不缓存的,它引入的js也是新的路径,而分片路径也是新的,所以界面就不会报错了。

这里需要注意的一点就是服务端新发布的代码最好可以兼容一下旧的界面,比如旧的界面要报个错什么的。

在前端开发中,JavaScript 代码本质上是明文传输和执行的,因此很容易被反编译、调试和分析。为了保护前端代码,尤其是商业产品或包含敏感逻辑的代码,通常会对 JavaScript 进行“**代码混淆**”或“**代码加固**”。虽然 JavaScript 无法像 Android APK 那样进行完全加密(因为浏览器需要执行),但我们可以通过多种手段提高代码的安全性。 --- ## 一、JavaScript 前端代码加固的常用手段 ### 1. **代码混淆(Obfuscation)** 通过工具将源代码重命名为无意义的变量名,打乱控制流,使代码难以阅读。 #### 工具推荐: - [JavaScript Obfuscator](https://obfuscator.io/) - UglifyJS - Terser #### 示例:使用 JavaScript Obfuscator ```bash npm install --save-dev javascript-obfuscator ``` 创建一个 `obfuscate.js` 文件: ```js const fs = require('fs'); const JavaScriptObfuscator = require('javascript-obfuscator'); const code = fs.readFileSync('src/index.js', 'utf-8'); const obfuscatedCode = JavaScriptObfuscator.obfuscate(code, { compact: true, controlFlowFlattening: true, // 控制流扁平化 controlFlowFlatteningThreshold: 0.75, numbersToExpressions: true, // 数字表达式混淆 rotateStringArray: true, stringArray: true, stringArrayEncoding: ['base64'], // 字符串加密 stringArrayThreshold: 0.75, deadCodeInjection: true, // 插入无效代码 deadCodeInjectionThreshold: 0.4 }); fs.writeFileSync('dist/index-obfuscated.js', obfuscatedCode.getObfuscatedCode()); ``` 运行脚本: ```bash node obfuscate.js ``` --- ### 2. **资源加密 + 动态加载** 将 JS 文件加密,通过动态加载和解密的方式运行。 #### 示例:加密并解密执行 加密脚本(Node.js): ```js const fs = require('fs'); const crypto = require('crypto'); function encrypt(code, key) { const cipher = crypto.createCipher('aes-256-cbc', key); let encrypted = cipher.update(code, 'utf8', 'base64'); encrypted += cipher.final('base64'); return encrypted; } const code = fs.readFileSync('src/secret.js', 'utf-8'); const encryptedCode = encrypt(code, 'my-secret-key'); fs.writeFileSync('dist/secret.enc.js', `eval(atob("${encryptedCode}").split('').reverse().join(''))`); ``` 前端解密执行: ```js // 加载加密脚本 const script = document.createElement('script'); script.src = 'secret.enc.js'; document.head.appendChild(script); ``` 注意:这种方式仍可通过浏览器调试器看到最终执行代码,但提高了阅读门槛。 --- ### 3. **WebAssembly** 将关键逻辑编译为 WebAssembly(Wasm),在前端调用。Wasm 是二进制格式,难以直接阅读。 #### 示例:使用 Emscripten 编译 C/C++ 为 Wasm 1. 安装 Emscripten: ```bash brew install emscripten ``` 2. 编写 C 文件 `add.c`: ```c int add(int a, int b) { return a + b; } ``` 3. 编译为 wasm: ```bash emcc -O3 -s WASM=1 -s EXPORTED_FUNCTIONS="['_add']" add.c -o add.wasm ``` 4. 在 HTML 中加载: ```html <!DOCTYPE html> <script> fetch('add.wasm').then(response => WebAssembly.instantiateStreaming(response) ).then(results => { const add = results.instance.exports._add; console.log(add(2, 3)); // 输出 5 }); </script> ``` --- ### 4. **代码分割 + 懒加载** 将敏感代码拆分为多个 chunk,延迟加载,防止一次性暴露。 ```js // Webpack 示例 import('./secretLogic').then(module => { module.runSecretFunction(); }); ``` --- ### 5. **反调试 + 检测开发者工具** 通过定时检测 `console`、`debugger`、`performance.now()` 等方式,防止调试。 ```js setInterval(() => { const start = performance.now(); debugger; const end = performance.now(); if (end - start > 100) { console.log("调试器被检测到"); // 可以阻止执行或发送日志 } }, 2000); ``` --- ## 二、注意事项 - **不能完全防止反编译**:JavaScript 必须在浏览器中执行,因此无法完全加密。 - **影响性能**:代码混淆和加密可能增加加载和执行时间。 - **SEO 友好性**:如果使用 WebAssembly 或懒加载,需注意 SEO。 - **混淆工具配置**:过度混淆可能导致代码崩溃,建议合理配置。 --- ## 三、总结 | 加固方式 | 说明 | 安全性 | 实现难度 | |------------------|----------------------------------|--------|-----------| | 代码混淆 | 变量名替换 + 控制流打乱 | 中 | 低 | | 资源加密加载 | 加密JS文件,运行时解密执行 | 中 | 中 | | WebAssembly | 编译C/C++为二进制,前端调用 | 高 | 高 | | 代码分割+懒加载 | 拆分敏感代码,延迟加载 | 低 | 中 | | 反调试检测 | 防止调试器附加 | 低 | 低 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值