Tìm kiếm trang web

javascript - Cách thiết lập basePath cho một ứng dụng NextJS xuất tĩnh


Tôi cần xây dựng và triển khai một ứng dụng React/NextJS lên máy chủ Weblogic J2ee với một bối cảnh cụ thể. Tôi có chút kinh nghiệm với React, nhưng mới bắt đầu làm quen với NextJS.

Hiện tại các bước xây dựng/kiểm tra là;

  • Tạo một ứng dụng NextJS vanilla

  • Thêm một next.config.js với module.export để thay đổi basepath

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

  • Thực thi npm run dev ứng dụng có sẵn trên 'http://localhost:3000/test'

  • Thêm một script xuất khẩu vào package.json "export": "next build && next export" để hỗ trợ xuất tĩnh

  • Thêm xuất khẩu bên dưới để giải quyết vấn đề 21079

    //https://github.com/vercel/next.js/issues/21079
    module.exports = {
      images: {
        loader: "imgix",
        path: "",
      }
    }
    
  • Đã thực thi npm run export để tạo một bản xuất HTML tĩnh. Việc xuất đã hoàn tất thành công vào thư mục out. Khi kiểm tra index.html trong thư mục out, tất cả các tham chiếu đến nội dung tĩnh vẫn bắt đầu với /_next/static chứ không phải với /test/_next/static.

    Vì vậy, điều này có thể là sự hiểu lầm từ phía tôi, xin hãy chỉnh sửa cho tôi nếu tôi sai.

  • Để có thể kiểm tra ứng dụng gốc trên máy chủ ứng dụng J2EE, nó phải được đóng gói thành tệp war. Để thực hiện điều này, tôi đã thêm tệp warpack/warpack.ts vào dự án.

    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);
        };
    });
  • Đã cài đặt các gói cần thiết cho webpack.ts

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

  • Đã thêm script "warpack": "next build && next export && node warpack/warpack.ts" để build, export và đóng gói ứng dụng tĩnh thành một file war.

  • Sau khi triển khai tệp war, trang có thể được tải trên http://something/test nhưng hiển thị một trang trống. Công cụ phát triển mạng cho thấy các yêu cầu được gửi tới gốc của máy chủ ứng dụng, không phải tới đường dẫn cơ sở đã cấu hình.

      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)
    

Câu trả lời #1

Bạn có thể sử dụng env check để chỉ gọi cho môi trường prod nếu bạn muốn như sau:

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

Câu trả lời số 2

Quá chú trọng vào giá trị basePath thay vì cú pháp đúng của next.config.js. Việc xuất module thứ hai trong next.config.js đã ghi đè module đầu tiên.

Sai

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

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

Đúng

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

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

}