วิธีบอก webpack dev server ให้บริการ index.html สำหรับเส้นทางใด ๆ


148

/arbitrary/routeตอบสนองเราเตอร์ช่วยให้ตอบสนองปพลิเคชันที่จะจับ เพื่อให้มันใช้งานได้ฉันต้องการเซิร์ฟเวอร์ของฉันเพื่อส่งแอป React ในทุกเส้นทางที่ตรงกัน

แต่เซิร์ฟเวอร์ dev ของ webpackไม่จัดการจุดสิ้นสุดตามอำเภอใจ

มีวิธีแก้ปัญหาที่นี่โดยใช้เซิร์ฟเวอร์ด่วนเพิ่มเติม วิธีการอนุญาตสำหรับ webpack-dev-server เพื่ออนุญาตจุดเข้าใช้งานจาก react-router

แต่ฉันไม่ต้องการไฟเซิร์ฟเวอร์ด่วนอื่นให้อนุญาตการจับคู่เส้นทาง ฉันแค่อยากบอก webpack dev server ให้ตรงกับ url และส่งแอปตอบกลับของฉันมาให้ฉัน กรุณา.


คุณเห็นReact Router Mega Demo แล้วหรือยัง
rojobuffalo

คำตอบ:


169

ฉันพบโซลูชันที่ง่ายที่สุดในการรวมการกำหนดค่าขนาดเล็ก:

  devServer: {
    port: 3000,
    historyApiFallback: {
      index: 'index.html'
    }
  }

ฉันพบนี้โดยไปที่: pushState กับ WEBPACK-DEV-SERVER


18
คุณยังสามารถใช้เป็นตัวเลือก CLI:--history-api-fallback
VonD

7
ฉันต้องใช้สิ่งนี้กับรุ่นใหม่กว่า 2devServer: { port: 3000, historyApiFallback: true },
Adrian Moisa

1
แน่นอนคุณต้องใช้ทั้งตัวเลือก cli "--history-api-fallback" และในการกำหนดค่าเซิร์ฟเวอร์ webpack dev ของคุณตั้งค่าความละเอียดไฟล์ดัชนีของคุณเช่นที่อธิบายไว้ในคำตอบนี้ข้างต้น
Jc Figueroa

86

ตัวเลือก historyApiFallbackบนเอกสารอย่างเป็นทางการสำหรับ webpack-dev-serverอธิบายอย่างชัดเจนว่าคุณจะประสบความสำเร็จได้อย่างไรโดยใช้

historyApiFallback: true

ซึ่งจะย้อนกลับไปที่ index.html เมื่อไม่พบเส้นทาง

หรือ

// output.publicPath: '/foo-app/'
historyApiFallback: {
  index: '/foo-app/'
}

1
อัปเดตลิงก์: webpack.js.org/configuration/dev-server/#devserver
jacob

แต่จริงๆแล้ว webpack-dev-server กำลังอยู่ในระหว่างการบำรุงรักษา มันคือตัวตายตัวแทนคือgithub.com/webpack-contrib/…ซึ่งสนับสนุนhistoryApiFallback
jacob

3
สำหรับใครก็ตามที่อ่านเรื่องนี้ในปี 2019 อ้างอิงจากgithub.com/webpack-contrib/webpack-serve#webpack-serve webpack-dev-serverเป็นผู้สืบทอดต่อwebpack-serveไม่ใช่วิธีอื่น ๆ ตามที่กล่าวไว้ในstackoverflow.com/questions/31945763/ ….
ur5us

ความคิดเห็นของ ur5us เป็นเท็จจริง ๆ webpack-เสิร์ฟเป็นผู้สืบทอดที่วางแผนไว้สำหรับ webpack-dev-server ฉันเป็นผู้เขียน webpack-เสิร์ฟและเป็นผู้ดูแลอดีตของ webpack-dev-server เมื่อฉันใช้เวลาสักพักสมาชิกองค์กรที่ขมขื่นเลิกใช้บริการ webpack และฉันก็ปล่อยมันออกมาภายใต้ส้อมของฉัน
shellscape

23

การเพิ่มเส้นทางสาธารณะเพื่อกำหนดค่าช่วยให้ webpack เข้าใจรูทจริง ( /) แม้ว่าคุณจะอยู่ในรูทีนย่อยเช่น/article/uuid

ดังนั้นแก้ไขการกำหนดค่า webpack ของคุณและเพิ่มสิ่งต่อไปนี้:

output: {
    publicPath: "/"
}

devServer: {
    historyApiFallback: true
}

หากไม่มีpublicPathทรัพยากรอาจไม่สามารถโหลดได้อย่างถูกต้องมีเพียง index.html

ทดสอบบน Webpack 4.6

ส่วนใหญ่ของการกำหนดค่า (เพื่อให้ได้ภาพที่ดีกว่า):

entry: "./main.js",
output: {
  publicPath: "/",
  path: path.join(__dirname, "public"),
  filename: "bundle-[hash].js"
},
devServer: {
  host: "domain.local",
  https: true,
  port: 123,
  hot: true,
  contentBase: "./public",
  inline: true,
  disableHostCheck: true,
  historyApiFallback: true
}

ว้าวสิ่งนี้ใช้ได้สำหรับฉันเช่นกัน! historyApiFallbackเคล็ดลับทำงานเฉพาะส่วนสุดท้ายของ URL ด้วยเหตุผลบางอย่าง /testจะทำงาน แต่/test/testจะให้ 404
อเล็กซ์ P.

นอกจากhistoryApiFallback: {index: '/'} หรือhistoryApiFallback: true(ทั้งสองทำงานให้ฉันด้วย) การตั้งค่าpublicPathยังเป็นสิ่งจำเป็นในกรณีของฉัน (เราเตอร์ 5.2)
Marcus Junius Brutus

17

ใช้งานได้สำหรับฉันเช่นนี้

devServer: {
    contentBase: "./src",
    hot: true,
    port: 3000,
    historyApiFallback: true

},

กำลังทำงานกับแอพปราบจลาจล


14

สถานการณ์ของฉันแตกต่างกันเล็กน้อยเนื่องจากฉันใช้ angular CLI กับ webpack และตัวเลือก 'eject' หลังจากเรียกใช้คำสั่งng eject ฉันปรับเปลี่ยนสคริปต์ npm ที่เลื่อนออกสำหรับ 'npm start' ใน package.json เพื่อผ่านใน --history-api-fallback flag

"start": "webpack-dev-server --port = 4200 - ประวัติ -iPi-fallback "

"scripts": {
"ng": "ng",
"start": "webpack-dev-server --port=4200 --history-api-fallback",
"build": "webpack",
"test": "karma start ./karma.conf.js",
"lint": "ng lint",
"e2e": "protractor ./protractor.conf.js",
"prepree2e": "npm start",
"pree2e": "webdriver-manager update --standalone false --gecko false --quiet",
"startold": "webpack-dev-server --inline --progress --port 8080",
"testold": "karma start",
"buildold": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"},

6

หากคุณเลือกที่จะใช้webpack-dev-serverคุณไม่ควรใช้แอปนี้เพื่อให้บริการแอป React ทั้งหมดของคุณ คุณควรใช้มันเพื่อให้บริการbundle.jsไฟล์ของคุณเช่นเดียวกับการอ้างอิงแบบคงที่ ในกรณีนี้คุณจะต้องเริ่มต้นเซิร์ฟเวอร์ 2 เครื่องหนึ่งตัวสำหรับจุดเข้า Node.js ซึ่งกำลังจะประมวลผลเส้นทางและให้บริการ HTML และอีกอันหนึ่งสำหรับชุดรวมและทรัพยากรคงที่

หากคุณต้องการเซิร์ฟเวอร์เดียวคุณต้องหยุดใช้webpack-dev-serverและเริ่มใช้webpack-dev-middlewareภายในแอปเซิร์ฟเวอร์ของคุณ มันจะประมวลผลการรวมกลุ่ม "ในทันที" (ฉันคิดว่ามันรองรับการแคชและการเปลี่ยนโมดูลร้อน) และตรวจสอบให้แน่ใจว่าการโทรของคุณbundle.jsมีความทันสมัยอยู่เสมอ


2
ฉันใช้ webpack-dev-server เพียงเพื่อการพัฒนาแหล่งโหลดแผนที่ร้อนแรงเป็นต้นมิฉะนั้นฉันจะมีเว็บไซต์คงที่ที่ฉันสามารถโฮสต์ไฟล์จากที่ใดก็ได้
eguneys

3

คุณสามารถเปิดใช้งานhistoryApiFallbackเพื่อให้บริการindex.htmlแทนข้อผิดพลาด 404 เมื่อไม่พบทรัพยากรอื่น ๆ ในตำแหน่งนี้

let devServer = new WebpackDevServer(compiler, {
    historyApiFallback: true,
});

หากคุณต้องการให้บริการไฟล์ที่แตกต่างกันสำหรับ URIs ที่แตกต่างกันคุณสามารถเพิ่มกฎการเขียนใหม่แบบพื้นฐานให้กับตัวเลือกนี้ index.htmlจะยังคงทำหน้าที่สำหรับเส้นทางอื่น ๆ

let devServer = new WebpackDevServer(compiler, {
    historyApiFallback: {
        rewrites: [
            { from: /^\/page1/, to: '/page1.html' },
            { from: /^\/page2/, to: '/page2.html' },
            { from: /^\/page3/, to: '/page3.html' },
        ]
    },
});

2

ฉันรู้ว่าคำถามนี้มีไว้สำหรับ webpack-dev-server แต่สำหรับทุกคนที่ใช้webpack-เสิร์ฟ 2.0 ด้วยwebpack 4.16.5 ; webpack-เสิร์ฟอนุญาตให้ add-on คุณจะต้องสร้างserve.config.js:

const serve = require('webpack-serve');
const argv = {};
const config = require('./webpack.config.js');

const history = require('connect-history-api-fallback');
const convert = require('koa-connect');

serve(argv, { config }).then((result) => {
  server.on('listening', ({ server, options }) => {
      options.add: (app, middleware, options) => {

          // HistoryApiFallback
          const historyOptions = {
              // ... configure options
          };

          app.use(convert(history(historyOptions)));
      }
  });
});

การอ้างอิง

คุณจะต้องเปลี่ยนสคริปต์ dev จากไปwebpack-servenode serve.config.js


2

สำหรับฉันฉันมีจุด "" ในเส้นทางของฉันเช่น/orgs.csvนั้นฉันจึงต้องใส่สิ่งนี้ลงใน webpack ของฉัน

devServer: {
  historyApiFallback: {
    disableDotRule: true,
  },
},

0

ฉันเห็นด้วยกับคำตอบที่มีอยู่ส่วนใหญ่

สิ่งหนึ่งที่สำคัญที่ผมอยากจะพูดถึงคือถ้าคุณตีปัญหาเมื่อตนเองโหลดหน้าเว็บบนเส้นทางลึกที่จะช่วยให้ทุกคน แต่ส่วนสุดท้ายของเส้นทางและ tacks ในชื่อของคุณjsไฟล์กำคุณอาจจำเป็นต้องมีการตั้งค่าพิเศษ (เฉพาะpublicPathการตั้งค่า )

ตัวอย่างเช่นถ้าฉันมีเส้นทาง/foo/barและไฟล์ Bundler bundle.jsของฉันถูกเรียกว่า เมื่อฉันพยายามรีเฟรชหน้าเพจด้วยตนเองฉันจะได้รับ 404 ว่า/foo/bundle.jsไม่พบ ที่น่าสนใจถ้าคุณลองโหลดใหม่จากเส้นทางที่/fooคุณเห็นไม่มีปัญหา (นี่เป็นเพราะทางเลือกจัดการมัน)

ลองใช้ด้านล่างร่วมกับการกำหนดค่าที่มีอยู่webpackเพื่อแก้ไขปัญหา output.publicPathเป็นกุญแจสำคัญ!

output: {
    filename: 'bundle.js',
    publicPath: '/',
    path: path.resolve(__dirname, 'public')
},
...
devServer: {
    historyApiFallback: true
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.