Далее JS развернуть по указанному c URL-пути - PullRequest
0 голосов
/ 28 февраля 2020

Я работаю над моим первым JS приложением. Когда я запускаю «npm run dev» или «npm run start», он развертывает мое приложение на

http://host:port/

Когда я перехожу на страницу, URL становится

http://host:port/page1

У меня должен быть свой собственный конкретный c URL, такой как

http://host:port/my-test-application/path-for-my-app/
http://host:port/my-test-application/path-for-my-app/page1

. Кроме того, в моем приложении есть много элементов для ссылок на другие области приложений, они также необходимы для go для URL с basePath, а не просто go на путь root.

Я также буду развертывать это приложение на разных серверах, которые будут иметь разные basePaths, поэтому это не может быть жестко задано в моем приложении.

Как я могу это сделать?

С другими приложениями, такими как реагировать / vue / angular / native JS, я просто собираю свое приложение и помещаю код сборки в папка «my-test-application / path-for-my-app» на моем сервере.

Я пробовал это с моим приложением Next JS, но я получил ошибку, что папка «.next» не смогла быть найден.

Я гуглил и мог найти некоторые ссылки на использование "assetPrefix" или использование "Zo указанные в другом месте». Однако я не совсем понимаю, что я должен делать.

Как развернуть мое приложение по указанному c URL

Решение 1: Реструктурировать "страницы" - не позволяет мне развертывать на разных серверах с разными basePaths

Я мог бы создать структуру папок внутри своего каталога "pages" и изменить все свои элементы, чтобы использовать эту структуру папок.

|- pages
     |- my-test-application
           |- path-for-my-app
                |- index.js
                |- page1.js


<Link href="/my-test-application/path-for-my-app/page1" >

Мне не нравится это решение, так как basePath жестко задан в моем приложении, в отличие от параметров развертывания.

Если бы я хотел развернуть свое приложение на 2 серверах с разными basePaths (т.е. ниже), мне пришлось бы у меня есть 2 версии кода.

http://host:port/my-test-application_1/path-for-my-app/page1
http://host:port/my-test-application_2/diff-path-for-my-app/page1

Обновлено: я обновил этот вопрос 5 марта, чтобы включить мою потребность в s для работы и одно решение, которое мне не нравится.

Ответы [ 3 ]

1 голос
/ 01 марта 2020

Вы можете использовать пользовательский сервер для создания следующей JS работы приложения с указанными вами c URL:

См. Пример здесь:

https://github.com/zeit/next.js/tree/canary/examples/custom-server-express

Ключевым моментом является добавление указанного вами c URL-адреса в качестве API, а затем перенаправление запроса пользователя на указанную вами c страницу, которую вы хотите обслуживать:

const express = require('express')
const next = require('next')

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = express()

  server.get('/my-test-application/path-for-my-app', (req, res) => {
    return app.render(req, res, '/index', req.query)
  })

  server.get('/my-test-application/path-for-my-app/page1', (req, res) => {
    return app.render(req, res, '/page1', req.query)
  })

  server.get('/posts/:id', (req, res) => {
    return app.render(req, res, '/posts', { id: req.params.id })
  })

  server.all('*', (req, res) => {
    return handle(req, res)
  })

  server.listen(port, err => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
})
0 голосов
/ 12 апреля 2020

Я решил это так, написав перенаправление в next.config. js:

const withImages = require('next-images')

module.exports = withImages(withSass({
    cssLoaderOptions: {
      url: false
    },
    //Might need to change it here, before going to the production
    assetPrefix: 'http://localhost:3000',
    postcssLoaderOptions: {
      config: {
        ctx: {
          theme: JSON.stringify(process.env.REACT_APP_THEME)
        }
      }
    }
})); 
0 голосов
/ 31 марта 2020

Я нашел решение, используя NGINX для обратного прокси URL с базовым путем.

Полезные ссылки

Изменения в приложениях

Зависимости

  • next-images: для импорта stati c изображений из "publi c" при использовании обратного прокси
  • @ zeit / next- css: для использовать файлы таблиц стилей
  • , а также обычные зависимости Next JS

next.config. js

Add a next .config. js "файл в root вашего приложения, так что вы можете указать" assetPrefix "и" publicRuntimeConfig.basePath "

  • assetPrefix: используется Next JS при доступе компоненты, таблицы стилей, страницы и т. д. c
  • publicRuntimeConfig.basePath: используется в s, поэтому укажите префикс для добавления к ссылке, используемый в тегах "sr c" элементов "" при использовании publi c images

Пример

const isProd = process.env.NODE_ENV === 'production'

// Enable importing of css stylesheets
const withCSS = require("@zeit/next-css");
const withImages = require('next-images');

/*
 * Gets the BASE_PATH from the command used to start this app.
 * If BASE_PATH is specified but it does not start with a "/" 
 * then add it. 
 */
function getBasePath() {
    var basePath = ''

    if (isProd && process.env.BASE_PATH){
        if (process.env.BASE_PATH.startsWith("/") ){
            basePath = process.env.BASE_PATH;
        } else {
            basePath = "/" + process.env.BASE_PATH;
        }
    } 

    console.log("getBasePath() : isProd = " + isProd);
    console.log("getBasePath() : basePath = " + basePath);

    return basePath
}

module.exports = withCSS(withImages({
    assetPrefix: getBasePath() ,

    publicRuntimeConfig: {
        basePath: getBasePath() ,
    },

}));

Stati c images

Используйте «next-images» для импорта изображений и ссылки на импортированный объект в sr c tags

Измените любые ссылки на ваши изображения stati c (в папке / publi c), чтобы они имели префикс базового пути. Например, мой компонент «Нижний колонтитул» имеет следующий

import '../stylesheets/main.css';

import img1 from '../public/image_name1.png'
import img2 from '../public/image_name2.png'

export default class o extends React.Component {

    render(){
        var prefix = publicRuntimeConfig.basePath
        return  (
            <div >
                <a className="icon" href="http://www.image_name.com" >
                    <img src={img1} alt="image_name1"/>
                </a>
                <a className="icon" href="http://www.image_name2.com">
                    <img  src={img1} alt="image_name2"/>
                </a>
            </div>
        );
    }
}

Примечание: я пытался использовать publicRuntimeConfig.basePath в качестве префикса к URL-адресу sr c (как показано ниже), но это не работает в моей развернутой среде (см. ниже)

    import getConfig from 'next/config'
    const { publicRuntimeConfig } = getConfig()
    ...
    ...
    <a className="icon" href="http://www.image_name.com" >
        <img src={`${publicRuntimeConfig.basePath}/image_name1.png`} alt="image_name1"/>
    </a>

Links

Измените ссылки, чтобы использовать префикс базового пути, например, в моем " Заголовок "компонент, у меня есть следующий

import Link from 'next/link';
import '../stylesheets/main.css';

import getConfig from 'next/config'
const { publicRuntimeConfig } = getConfig()

const detailId1 = "banana"

const Header = () => (
    <div>
        <div>
            <Link href={`${publicRuntimeConfig.basePath || ''}/`}>
                <a className="linkStyle">Home</a>
            </Link>

            <Link href={`${publicRuntimeConfig.basePath || ''}/about`} >
                <a className="linkStyle">About</a>
            </Link>

            <Link href={`${publicRuntimeConfig.basePath || ''}/details/[id]`} 
                  as= {`${publicRuntimeConfig.basePath || ''}/details/${detailId1}`} >
                <a className="linkStyle">Details Var 1</a>
            </Link>
        </div>
  </div>
);

export default Header;

Примечание: в блоге https://levelup.gitconnected.com/deploy-your-nextjs-application-on-a-different-base-path-i-e-not-root-1c4d210cce8a, он содержит" Link.tsx ", который добавляет префикс для вы, так что вы просто используете этот компонент Link (импортируйте Link из "./Link.tsx";), а не следующую JS версию (импортируйте Link из 'next / link';). Однако этот «Link.tsx» не работает для меня, когда в URL-адресах ссылок есть переменные.

Запуск вашего следующего js приложения

При локальном запуске приложения, когда вам НЕ нужен базовый путь, вы можете просто запустить

npm run dev

Поскольку BASE_PATH не указан, ваше приложение должно быть доступно из "http://localhost: 3000 " и ваши значения sr c должны быть "/image_name1.png", а когда вы наводите курсор мыши на свои s, вы увидите ссылку "http://localhost: 3000 / pagename "

Когда Вы хотите запустить с базовым путем, выполните следующие действия:

export BASE_PATH=a/b
npm run dev

Примечание: по какой-то причине в моей среде, если я укажу "export BASE_PATH = / a / b" (/ в начале путь) Я получаю каталог папки, добавленный в начало пути. Поэтому я указываю это без начального / и код в next.config. js добавляет начальный /, если необходимо.

Вы не можете получить доступ к своему приложению в "http://localhost : 3000", поскольку у вас установлен базовый путь / assetPrefix / publicRuntimeConfig.basePath. Теперь вам нужен обратный прокси.

NGINX: обратный прокси

Я обнаружил, что проще всего было использовать изображение NGINX docker. Вам нужно запустить NGINX с конфигурацией, содержащей перенаправление на ваше приложение Next JS.

Создайте папку и добавьте в эту папку файл "default.conf". Убедитесь, что путь, который вы указали в своем «местоположении», - это тот же путь, который вы указали для BASE_PATH при запуске следующего js приложения.

server {
    listen 80;
    server_name  localhost;

    location /a/b/ {
        proxy_pass http://myhost:3000/;
    }       
}

Важные замечания: должен иметь конечный / в конце URL-адреса proxy_pass, в противном случае дополнительные пути не будут переданы вашему Next JS apoplication

, если вы используете переменную в местоположении, вы должны убедиться, что вы включили передачу по путям

пример

location ~ /a/b/(.*)$ {  
    set $upstream http://myhost:3000/$1;
    proxy_pass $upstream;
}

В командной строке из этого каталога запустите образ NGINX docker, сказав ему использовать ваш файл конфигурации.

docker run --name mynginx1 -v C:/zNGINX/testnginx/conf:/etc/nginx/conf.d -p 80:80 -d nginx
  • имя контейнера docker - "mynginx1"
  • , параметр v указывает ему копировать любые файлы из "C: / zNGINX / testnginx / conf" на вашем компьютере в "/ Каталог etc / nginx / conf.d "в контейнере docker. Это скопирует ваш файл «default.conf» в контейнер docker, а NGINX прочитает этот файл конфигурации.
  • Примечание. Убедитесь, что в вашем пути есть каталог "conf.d" для местоположения docker (": /etc/nginx/conf.d"), блоги, которые я читал, не включали эту часть, он только указывает ": / etc / nginx /", и без него изображение не запускается.
  • параметр p указывает запускать NGINX на порту 80

Go на следующий URL

http://localhost:80/a/b/

NGINX перенаправит этот URL на "http://localhost: 3000 ". Поэтому ваше приложение теперь должно быть доступно по URL с базовым путем. Нажатие на s должно работать, ссылка должна содержать базовый путь, который идет к NGINX, который перенаправляет обратно к приложению, удаляющему базовый путь, оставляя любые другие пути.

Развертывание сервера реального мира с использованием Docker

Если вы развертываете свое приложение на сервере, в отличие от локального запуска, вы можете создать свое приложение и затем скопировать соответствующие файлы / папки на серверный компьютер. Убедитесь, что у вас установлена ​​BASE_PATH при сборке и запуске приложения

export BASE_PATH=a/b
npm run build

cp package*.json [server_location]
cp next.config.js [server_location]
cp ./next [server_location]

, затем на этом сервере выполните

npm install
export BASE_PATH=a/b
npm run start   

Примечание. Если у вас есть изображения в "publi c », на который вы ссылаетесь в своем приложении, используйте« next-images »и импортируйте изображение, а не используйте publicRuntimeConfig.basePath в качестве префикса. Когда я сделал последнее, изображения не были найдены. Смотрите раздел об изображениях для примеров.

...