簡體   English   中英

如何在不捆綁的情況下將為 AMD 編寫的代碼重寫/重新打包到 CommonJs?

[英]How can I rewrite/repack code written for AMD to CommonJs without bundling it?

我有一個使用 AMD 模塊為瀏覽器編寫的項目,現在我需要在 nodejs 中運行相同的代碼,所以我需要將每個文件重寫為使用 CommonJs 模塊。 我試過 webpack,但它給了我一個我不需要的包。 我想要的只是讓我的文件保持原樣,但重寫define(.. imports to require(..)

感謝 Felix Kling 的建議,我在打字稿中編寫了以下轉換器

import { FileInfo, API, Options } from 'jscodeshift';
import { resolve, normalize, relative } from 'path';

export default function transformer(file: FileInfo, api: API, options: Options) {
    const { j } = api;
    return j(file.source)
        .find(j.ExpressionStatement, { expression: { callee: { name: 'define' } } })
        .replaceWith(({ node }) => {
            const { expression: defineCallExpression } = node;

            if (defineCallExpression.type !== 'CallExpression') return crash('No call to define function of AMD.');
            const [moduleLocationsArray, callback] = defineCallExpression.arguments;
            if (callback.type !== 'FunctionExpression') return;
            if (moduleLocationsArray.type !== 'ArrayExpression') return;

            const imports = moduleLocationsArray.elements.map((element, index) => {
                if (element === null) return crash('Module name skipped.');
                if (element.type !== 'Literal') return crash('Module name is not a literal');
                const param = callback.params[index];
                if (param.type !== 'Identifier') return crash('Module parameter is not an identifier.');
                return {
                    location: element.value as string,
                    name: param.name,
                };
            }).filter(pair => shouldKeepModule(pair.location));

            const filePath = normalize(resolve(__dirname, file.path));
            const baseDir = normalize(resolve(__dirname, options.where));
            const importStatements = imports.map(({name, location}) => {
                const modulePath = normalize(resolve(baseDir, location));
                const relativeModuleName = slashings(relative(filePath, modulePath));
                const text = `const ${name} = require('${relativeModuleName}');`;
                const statement = api.j(text, options);
                return statement;
            });
            const statementsBefore = callback.body.body;
            const statementsAfter = [...importStatements, ...statementsBefore];
            return statementsAfter;
        })
        .toSource();
}

function shouldKeepModule(location: string): boolean {
    return location !== 'module' && location !== 'exports' && location !== 'require';
}
function crash(message: string): never { throw new Error(message); }
function slashings(text: string): string { return text.replace(/\\/g, '/'); }

使用以下tsconfig.json

{
    "compileOnSave": true,
    "compilerOptions": {
        "strict": true,
        "target": "es6",
        "module": "commonjs",
        "lib": ["es6"],
        "types": ["node", "jscodeshift"],
        "outDir": "../../node_modules/amd-to-commonjs"
    }
}

使用以下package.json

{
    "private": true,
    "devDependencies": {
        "@types/node": "7.0.4",
        "@types/jscodeshift": "0.6.0",
        "jscodeshift": "0.6.3",
        "typescript": "3.4.0-dev.20190227"
    }
}

通過以下命令構建

npm install
node ../../node_modules/typescript/bin/tsc --project ./

並通過以下命令運行

node ../../node_modules/jscodeshift/bin/jscodeshift.js --transform=../../node_modules/amd-to-commonjs/transformer.js --where=../../scripts/built ../../scripts/built

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM