جافاسكريبت - كيفية تعيين basePath لتطبيق NextJS مصدّر بشكل ثابت


أحتاج إلى بناء ونشر تطبيق React/NextJS على خادم Weblogic J2ee بسياق محدد. لدي بعض الخبرة في React، لكنني أخوض خطواتي الأولى مع NextJS.

حاليًا خطوات البناء/التحقق هي؛

  • أنشئ تطبيق NextJS بسيط

  • أضف ملف next.config.js مع module.export لتغيير المسار الأساسي

    module.exports={ basePath: '/test' }

  • نفّذ npm run dev التطبيق متاح على 'http://localhost:3000/test'

  • أضف نص تصدير إلى الملف package.json "export": "next build && next export" لدعم التصدير الثابت

  • أضف التصدير أدناه لحل المشكلة 21079

    //https://github.com/vercel/next.js/issues/21079
    module.exports = {
      images: {
        loader: "imgix",
        path: "",
      }
    }
    
  • تم تنفيذ npm run export لإنشاء تصدير HTML ثابت. تم إكمال التصدير بنجاح إلى مجلد out. عند فحص index.html في مجلد out، جميع الإشارات إلى المحتوى الثابت لا تزال تبدأ بـ /_next/static وليست بـ /test/_next/static.

    لذلك قد يكون هذا سوء تفسير من جانبي، من فضلك صحح لي إذا كنت مخطئًا هنا.

  • لكي تكون قادرًا على اختبار التطبيق الافتراضي على خادم تطبيقات J2EE، يجب تعبئته في ملف war. لتحقيق ذلك، قمت بإضافة الملف warpack/warpack.ts إلى المشروع.

    const fs = require('fs');
    const archiver = require('archiver');
    const rimraf = require('rimraf') ;
    
    const distFolder = 'dist' ;
    const warFile = distFolder + '/test.war';
    const buildFolder = 'out';
    const contextRoot = 'test';
    
    // Destroy dist folder
    rimraf(distFolder, (error) => { 
        if (!error) {       
            // Create dist folder
            if (!fs.existsSync(distFolder)){
                fs.mkdirSync(distFolder);
            }
        
            const output = fs.createWriteStream(warFile);
            const archive = archiver('zip', {});
        
            output.on('close', () => {
                console.log('war (' + warFile + ') ' + archive.pointer() + ' total bytes');
            });
        
            // write archive to output file
            archive.pipe(output);
            // add build folder to archive
            archive.directory(buildFolder,'');
            // add weblogic.xml
            const weblogicXML = '<?xml version="1.0" encoding="UTF-8"?><weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.2/weblogic-web-app.xsd"><weblogic-version>10.3.6</weblogic-version><context-root>' + contextRoot '</context-root><description>Test NextJS</description></weblogic-web-app>'
            archive.append(weblogicXML,{ name: 'WEB-INF/weblogic.xml' });
        
            const manifestMF = 'Manifest-Version: 1.0\nBuild-Tag: 0.0.1-SNAPSHOT\nWeblogic-Application-Version: 0.0.1-SNAPSHOT';
            archive.append(manifestMF,{ name: 'META-INF/MANIFEST.MF' });
        
            archive.finalize();
        
        } else {
            console.log('Failed to delete "' + distFolder + '" folder.') ;
            process.exit(1);
        };
    });
  • تم تثبيت الحزم المطلوبة لـ webpack.ts

    npm install fs --save-dev npm install rimraf --save-dev npm install archiver --save-dev

  • تمت إضافة السكربت "warpack": "next build && next export && node warpack/warpack.ts" للبناء والتصدير وتجميع التطبيق الثابت إلى ملف war.

  • بعد نشر ملف الحرب يمكن تحميل الصفحة على http://something/test لكنها تعرض صفحة فارغة. تشير أدوات تطوير الشبكة إلى أن الطلبات تُرسل إلى جذر خادم التطبيق، وليس إلى المسار الأساسي المُكوَّن.

      GET http://host:8001/static/css/main.09371e9d.chunk.css     net::ERR_ABORTED 404 (Not Found)
      GET http://host/static/js/2.0850eeb7.chunk.js net::ERR_ABORTED 404 (Not Found)
      GET http://host/static/js/main.dc0c945b.chunk.js net::ERR_ABORTED 404 (Not Found)
    

الإجابة رقم 1

يمكنك استخدام env للتحقق للاستدعاء فقط في بيئة prod إذا كنت ترغب في ذلك كما يلي:

module.exports = {
    basePath: "/test"
    assetPrefix: process.env.NODE_ENV === "production" ? "/test/" : undefined,
}

الإجابة رقم 2

التركيز الزائد على قيمة basePath بدلًا من التركيز على الصياغة الصحيحة لـ next.config.js. تصدير الوحدة الثاني في next.config.js تجاوز الأول.

خطأ

module.exports = { 
  basePath: '/test' 
}

//https://github.com/vercel/next.js/issues/21079
module.exports = {
  images: {
    loader: "imgix",
    path: "",
  }
}

صحيح

module.exports = { 
  basePath: '/test',
  assetPrefix: "/test/",

  //https://github.com/vercel/next.js/issues/21079
  images: {
    loader: "imgix",
    path: ""
  }

}