You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过用户脚本修改Webpack模块内代码以完整显示Twitter/X长推文

如何通过用户脚本修改Webpack模块内代码以完整显示Twitter/X长推文

嘿,这个问题我之前也碰到过,Webpack打包后的模块确实有点棘手,但有两种可行的方案能帮你实现完整显示长推文的需求,我给你详细拆解下:

方案一:拦截API请求替换推文内容(更稳定)

这种方法不用碰Webpack的模块代码,而是直接在Twitter获取推文数据的阶段,把full_text替换成note_tweet.text,让原页面代码自动用完整文本渲染。好处是Webpack模块ID变了也不影响,容错性更强。

你可以直接用这个用户脚本:

// ==UserScript==
// @name         Twitter/X 完整显示长推文
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  自动显示完整长推文,无需点击"查看更多"
// @author       自定义名称
// @match        https://twitter.com/*
// @match        https://x.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 拦截原生fetch请求
    const originalFetch = window.fetch;
    window.fetch = async function(...args) {
        const response = await originalFetch.apply(this, args);

        // 只处理推文相关的API请求
        const requestUrl = args[0];
        if (typeof requestUrl === 'string' && (requestUrl.includes('TweetDetail') || requestUrl.includes('timeline'))) {
            // 克隆响应避免原响应被消耗
            const clonedResp = response.clone();
            try {
                const data = await clonedResp.json();

                // 递归处理所有推文(包括转发、引用的推文)
                const processTweet = (tweet) => {
                    if (tweet.note_tweet?.text) {
                        // 把full_text和text替换成完整的note_tweet内容
                        tweet.full_text = tweet.note_tweet.text;
                        tweet.text = tweet.note_tweet.text;
                    }
                    // 处理嵌套的转发/引用推文
                    if (tweet.retweeted_status) processTweet(tweet.retweeted_status);
                    if (tweet.quoted_status) processTweet(tweet.quoted_status);
                    return tweet;
                };

                // 处理推文详情页的API结构
                if (data.data?.threaded_conversation_with_injections_v2) {
                    data.data.threaded_conversation_with_injections_v2.instructions.forEach(inst => {
                        if (inst.addEntries) {
                            inst.addEntries.entries.forEach(entry => {
                                const tweetResult = entry.content?.itemContent?.tweet_results?.result;
                                if (tweetResult) processTweet(tweetResult);
                            });
                        }
                    });
                }
                // 处理首页/时间线的API结构
                else if (data.data?.home_timeline_urt) {
                    data.data.home_timeline_urt.instructions.forEach(inst => {
                        if (inst.addEntries) {
                            inst.addEntries.entries.forEach(entry => {
                                const tweetResult = entry.content?.itemContent?.tweet_results?.result;
                                if (tweetResult) processTweet(tweetResult);
                            });
                        }
                    });
                }

                // 返回修改后的新响应
                return new Response(JSON.stringify(data), {
                    status: response.status,
                    statusText: response.statusText,
                    headers: response.headers
                });
            } catch (err) {
                // 解析失败时返回原响应,避免影响页面
                return response;
            }
        }
        return response;
    };
})();

方案二:直接Patch Webpack模块(更直接)

如果你还是想修改那个Webpack模块里的代码,可以通过定位Webpack的模块缓存来替换目标函数。不过要注意:Twitter更新后模块ID(比如你说的147093)可能会变,到时需要重新用DevTools查找。

这个脚本需要在页面加载初期运行:

// ==UserScript==
// @name         Twitter/X 补丁Webpack模块显示长推文
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  修改Webpack模块内的代码,直接使用note_tweet.text
// @author       自定义名称
// @match        https://twitter.com/*
// @match        https://x.com/*
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // 等待Webpack模块加载完成
    function waitForWebpack() {
        // Twitter的Webpack模块通常存在window.__webpack_modules__中
        if (window.__webpack_modules__) {
            const targetModuleId = '147093'; // 你找到的模块ID
            const originalModule = window.__webpack_modules__[targetModuleId];
            
            if (originalModule) {
                // 重写目标模块
                window.__webpack_modules__[targetModuleId] = function(e, n, d) {
                    // 先执行原模块的所有逻辑
                    originalModule(e, n, d);
                    // 获取原导出的h函数(模块导出的Z就是h)
                    const originalH = n.Z;
                    // 替换h函数,加入我们的逻辑
                    n.Z = function(...args) {
                        const tweetData = args[0];
                        // 先调用原函数拿到处理后的对象
                        const processedTweet = originalH.apply(this, args);
                        // 如果存在note_tweet.text,替换text和full_text
                        if (tweetData.note_tweet?.text) {
                            processedTweet.text = tweetData.note_tweet.text;
                            processedTweet.full_text = tweetData.note_tweet.text;
                        }
                        return processedTweet;
                    };
                    console.log('Webpack模块已成功补丁!');
                };
            } else {
                // 模块还没加载,100ms后重试
                setTimeout(waitForWebpack, 100);
            }
        } else {
            setTimeout(waitForWebpack, 100);
        }
    }

    waitForWebpack();
})();

两种方案的优缺点对比

  • API拦截方案:稳定性高,不受Webpack模块更新影响;缺点是需要适配Twitter的API结构,如果API返回格式变了,需要调整脚本里的遍历逻辑。
  • Webpack补丁方案:逻辑更直接,完全对应你找到的代码问题;缺点是模块ID可能随Twitter更新变化,到时需要重新在DevTools里定位模块。

如果之后Twitter改了API结构或者模块ID,你可以打开浏览器DevTools的Sources面板,重新查找对应的请求或模块位置调整脚本就行。

备注:内容来源于stack exchange,提问作者Ahmad Hk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 12:04:31