ওয়েবপ্যাক-ডেভ-সার্ভারকে কীভাবে বিক্রিয়া-রাউটার থেকে প্রবেশের পয়েন্টগুলি মঞ্জুরি দেবে


117

আমি এমন একটি অ্যাপ তৈরি করছি যা প্রতিক্রিয়া-রাউটারের পাশাপাশি বিকাশে ওয়েবপ্যাক-ডেভ-সার্ভার ব্যবহার করে।

দেখে মনে হচ্ছে যে ওয়েবপ্যাক-ডেভ-সার্ভারটি এমন এক ধারণা ধরে তৈরি করা হয়েছে যে আপনার এক জায়গায় (যেমন "/") সর্বজনীন প্রবেশের পয়েন্ট থাকবে, তবে প্রতিক্রিয়া-রাউটারটি সীমাহীন পরিমাণে প্রবেশের পয়েন্টগুলিকে অনুমতি দেয়।

আমি ওয়েবপ্যাক-ডেভ-সার্ভারের সুবিধাগুলি চাই, বিশেষত গরম পুনরায় লোডিং বৈশিষ্ট্য যা উত্পাদনশীলতার জন্য দুর্দান্ত, তবে আমি এখনও প্রতিক্রিয়া-রাউটারে সেট রুটগুলি লোড করতে সক্ষম হতে চাই।

তারা কীভাবে এটিকে বাস্তবায়ন করতে পারে যে তারা একসাথে কাজ করবে? আপনি কি ওয়েবপ্যাক-দেব-সার্ভারের সামনে এমনভাবে কোনও এক্সপ্রেস সার্ভার চালাতে পারবেন?


আমার এখানে কোনও কিছুর একটি অত্যন্ত হ্যাকি সংস্করণ রয়েছে তবে এটি ভঙ্গুর এবং কেবল সহজ রুটগুলিকে মেলানোর অনুমতি দেয়: github.com/natew/react-base (মেক-ওয়েবপ্যাক-কনফিগারেশন দেখুন) এবং (অ্যাপ্লিকেশন / রুটস.জেএস)
নাথান ভিয়েনার্ট

আপনি নাথন এই সমস্যাটি সমাধান করতে পরিচালনা করেছেন? যদি তাই হয়, কিভাবে? দয়া করে এখানে আমার প্রশ্নের উত্তর দেওয়ার চেষ্টা করুন stackoverflow.com/questions/31091702/… । ধন্যবাদ..!
সুডোপ্লাজ

উত্তর:


69

আমি এটি অর্জনের জন্য একটি প্রক্সি স্থাপন করেছি:

আপনার নিয়মিত এক্সপ্রেস ওয়েবসার্ভার রয়েছে যা কোনও রুটে সূচক html পরিবেশন করে, যদি তা কোনও সম্পদ রুট ব্যতীত। যদি এটি কোনও সম্পদ হয়, অনুরোধটি ওয়েব-ডেভ-সার্ভারে প্রক্সি হয়ে যায়

আপনার প্রতিক্রিয়া হট এন্ট্রিপয়েন্টগুলি এখনও ওয়েবপ্যাক ডেভ সার্ভারে সরাসরি নির্দেশ করবে, তাই গরম পুনরায় লোডিং এখনও কাজ করে।

ধরে নেওয়া যাক আপনি 8081 তে ওয়েবপ্যাক-ডেভ-সার্ভার এবং আপনার প্রক্সিটি 8080 তে চালাচ্ছেন run আপনার সার্ভার.জেএস ফাইলটি দেখতে এইরকম হবে:

"use strict";
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./make-webpack-config')('dev');

var express = require('express');
var proxy = require('proxy-middleware');
var url = require('url');

## --------your proxy----------------------
var app = express();
## proxy the request for static assets
app.use('/assets', proxy(url.parse('http://localhost:8081/assets')));

app.get('/*', function(req, res) {
    res.sendFile(__dirname + '/index.html');
});


# -----your-webpack-dev-server------------------
var server = new WebpackDevServer(webpack(config), {
    contentBase: __dirname,
    hot: true,
    quiet: false,
    noInfo: false,
    publicPath: "/assets/",

    stats: { colors: true }
});

## run the two servers
server.listen(8081, "localhost", function() {});
app.listen(8080);

ওয়েবপ্যাক কনফিগারেশনে এখন আপনার এন্ট্রিপয়েন্টগুলি করুন:

 entry: [
     './src/main.js',
     'webpack/hot/dev-server',
     'webpack-dev-server/client?http://localhost:8081'
 ]

হট্রিলোডের জন্য সরাসরি কলটি 8081 নোট করুন

আপনি output.publicPathবিকল্পটিতে একটি নিখুঁত url পাস করেছেন তাও নিশ্চিত করুন :

 output: {
     publicPath: "http://localhost:8081/assets/",
     // ...
 }

1
আরে, এটা দুর্দান্ত। আমি আসলে এর ঠিক আগে এই সেটআপে এসে পৌঁছলাম এবং একটি উত্তর পোস্ট করতে যাচ্ছিলাম তবে আমি মনে করি আপনি আরও ভাল কাজ করেছেন।
নাথান ভিনিয়ার্ট

1
একটি প্রশ্ন, সম্পর্কিত নয় এমন ধরণের যাতে প্রয়োজন হলে আমি একটি নতুন প্রশ্ন খুলতে পারি তবে আমি লক্ষ্য করেছি যে এখন ওয়েবপ্যাক ডেভ সার্ভার থেকে কনসোল আউটপুট প্রবাহিত নয়। আগে, আপনি এটি সংকলন করতে পারতেন এবং পার্সেন্টগুলি বৃদ্ধি দেখতে পেতেন, এখন এটি সংকলনের পরে আউটপুটগুলি কেবল অবরুদ্ধ করে।
নাথান ভিনিয়ার্ট

ভালই হয়েছে। এটি ঠিক কীভাবে করা উচিত। আমি output.publicPathবিকল্পটি সম্পর্কে একটি নোট যুক্ত করেছি , এটিও একটি পরম ইউআরএল হওয়া উচিত।
টোবিয়াস কে।

5
পরিবর্তে একটি বিল্ট-ইন ওয়েবপ্যাক প্রক্সি ব্যবহার করা সহজ হবে। সুতরাং আপনি নিজে সার্ভারে হস্তক্ষেপ করবেন না, আপনি সার্ভারটিকে খাঁটি ছেড়ে চলেছেন । পরিবর্তে, আপনি ওয়েবপ্যাক কনফিগারেশনে কিছুটা (3-5 লাইন) যোগ করুন। আপনি শুধুমাত্র দেব উদ্দেশ্যগুলির জন্য কেবল ডেভ স্ক্রিপ্টগুলি সংশোধন করেছেন এবং উত্পাদনের কোডটি (সার্ভার.জেএস) শান্তিতে রেখেছেন (আপনার সংস্করণে ভিন্ন নয়) এবং ইমো এটিই যাওয়ার উপযুক্ত উপায়।
jalooc

3
এই উত্তরটি এখনও কিছুটা সময়সীমার পরেও সঠিক। আরও সোজা উপায় এখন উপলব্ধ, দেখুন historyApiFallback
ইউজিন কুলাবোভভ

102

আপনি সেট করা উচিত historyApiFallbackএর WebpackDevServerএটির জন্য কাজ করতে সত্য হিসেবে। এখানে একটি ছোট উদাহরণ (আপনার উদ্দেশ্যগুলি মাপসই টুইঙ্ক):

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');

var config = require('./webpack.config');


var port = 4000;
var ip = '0.0.0.0';
new WebpackDevServer(webpack(config), {
    publicPath: config.output.publicPath,
    historyApiFallback: true,
}).listen(port, ip, function (err) {
    if(err) {
        return console.log(err);
    }

    console.log('Listening at ' + ip + ':' + port);
});

আপনি আপনার
সূচক html এর

7
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। ওয়েবপ্যাক ডেভ সার্ভার ডকস থেকে: "আপনি যদি HTML5 ইতিহাস এপিআই ব্যবহার করে থাকেন তবে আপনার সম্ভবত 404 প্রতিক্রিয়াগুলির পরিবর্তে আপনার সূচক। Html পরিবেশন করা দরকার যা ইতিহাস সেট করেই করা যেতে পারে অ্যাপিফ্যালব্যাক: সত্য" যদি আমি প্রশ্নটি সঠিকভাবে বুঝতে পারি তবে এটি সমাধান হবে সমস্যাটি.
সেবাস্তিয়ান

খুব সহজ ... আপনাকে ধন্যবাদ!
smnbbrv

1
@ smnbbrv কোন প্রোব নেই। এটি আসলে সংযোগ-ইতিহাস-এপি-ফ্যালব্যাকটি নীচে ব্যবহার করে এবং আপনি যদি কেবলমাত্র পরিবর্তে চান তবে মিডলওয়্যার নির্দিষ্ট বিকল্পগুলির সাহায্যে কোনও বস্তু পাস করতে পারেন true
জুহো ভেস্পসালিনেন

1
বা যদি আপনি ক্লিপটি ব্যবহার করছেন,webpack-dev-server --history-api-fallback
লেভি

27

অন্য যে কেউ এখনও এই উত্তরটির সন্ধান করতে পারে। আমি একটি সহজ প্রক্সি বাইপাস একসাথে রেখেছি যা খুব বেশি ঝামেলা ছাড়াই এটি অর্জন করে এবং কনফিগারেশনটি ওয়েবপ্যাক.কনফিগ.জেজে চলে যায়

আমি নিশ্চিত যে রেগেক্স ব্যবহার করে স্থানীয় সামগ্রীর জন্য পরীক্ষার আরও অনেক মার্জিত উপায় আছে তবে এটি আমার প্রয়োজনের জন্য কাজ করে।

devServer: {
  proxy: { 
    '/**': {  //catch all requests
      target: '/index.html',  //default target
      secure: false,
      bypass: function(req, res, opt){
        //your custom code to check for any exceptions
        //console.log('bypass check', {req: req, res:res, opt: opt});
        if(req.path.indexOf('/img/') !== -1 || req.path.indexOf('/public/') !== -1){
          return '/'
        }

        if (req.headers.accept.indexOf('html') !== -1) {
          return '/index.html';
        }
      }
    }
  }
} 

আমার জন্য ভাল কাজ করেছে
নাথ

সুন্দরভাবে কাজ করেছেন! .. ধন্যবাদ!
ধ্রুমিল ভানখর

এটি কেবল নির্ভুল উত্তর, দ্রুত এবং সহজ।
ডোমিনো

12

আপনি যদি সিএলআই ব্যবহার করে ওয়েবপ্যাক-ডেভ-সার্ভার চালিয়ে যাচ্ছেন তবে আপনি ওয়েবপ্যাক.config.js ডেভ সার্ভার অবজেক্টকে পাস করার মাধ্যমে এটি কনফিগার করতে পারেন:

module.exports = {
  entry: "index.js",
  output: {
    filename: "bundle.js"
  },
  devServer: {
    historyApiFallback: true
  }
}

এটি 404 টির মুখোমুখি হওয়ার পরে সূচি html এ পুনর্নির্দেশ করবে।

দ্রষ্টব্য: আপনি যদি সর্বজনীনপথ ব্যবহার করছেন তবে আপনাকে এটি ডেভ সার্ভারেও পাস করতে হবে:

module.exports = {
  entry: "index.js",
  output: {
    filename: "bundle.js",
    publicPath: "admin/dashboard"
  },
  devServer: {
    historyApiFallback: {
      index: "admin/dashboard"
    }
  }
}

আউটপুটের প্রথম কয়েকটি লাইন দেখে আপনি যাচাই করতে পারেন যে "404s এর অংশটি পিছনে ফিরে আসবে: পথে ") :

এখানে চিত্র বর্ণনা লিখুন


11

আরও সাম্প্রতিক উত্তরের জন্য ওয়েবপ্যাকের বর্তমান সংস্করণ (৪.১.১) আপনি কেবল এটির মতো ওয়েবপ্যাক.কনফিগ.জেজে সেট করতে পারেন:

const webpack = require('webpack');

module.exports = {
    entry: [
      'react-hot-loader/patch',
      './src/index.js'
    ],
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /\.css$/,
                exclude: /node_modules/,
                use: ['style-loader','css-loader']
            }
        ]
    },
    resolve: {
      extensions: ['*', '.js', '.jsx']  
    },
    output: {
      path: __dirname + '/dist',
      publicPath: '/',
      filename: 'bundle.js'
    },
    plugins: [
      new webpack.HotModuleReplacementPlugin()
    ],
    devServer: {
      contentBase: './dist',
      hot: true,
      historyApiFallback: true
    }
  };

গুরুত্বপূর্ণ অংশটি হ'ল historyApiFallback: true। কাস্টম সার্ভার চালানোর দরকার নেই, কেবল ক্লিপটি ব্যবহার করুন:

"scripts": {
    "start": "webpack-dev-server --config ./webpack.config.js --mode development"
  },

2

আপনি যখন আইসোমরফিক অ্যাপটি চালাবেন তখন আমি মামলার উত্তরে যুক্ত করতে চাই (যেমন রেন্ডারিং রিঅ্যাক্টিনেন্ট উপাদান সার্ভার-সাইডটি উপস্থাপন করুন))

এই ক্ষেত্রে আপনি সম্ভবত আপনার প্রতিক্রিয়া উপাদানগুলির কোনও পরিবর্তন করলে সার্ভারটি স্বয়ংক্রিয়ভাবে পুনরায় লোড করতে চান। আপনি pipingপ্যাকেজটি দিয়ে এটি করেন । আপনাকে যা করতে হবে তা হ'ল এটি ইনস্টল করুন এবং require("piping")({hook: true})আপনার সার্ভার.জেএস এর শুরুতে কোথাও যুক্ত করুন । এটাই. আপনি এর দ্বারা ব্যবহৃত কোনও উপাদান পরিবর্তন করার পরে সার্ভারটি পুনরায় চালু হবে।

যদিও এটি আরও একটি সমস্যার উত্থাপন করেছে - আপনি যদি আপনার এক্সপ্রেস সার্ভারের একই প্রক্রিয়া থেকে ওয়েবপ্যাক সার্ভার চালান (উপরের স্বীকৃত উত্তরের মতো), ওয়েবপ্যাক সার্ভারটিও পুনরায় চালু হবে এবং প্রতিবার আপনার বান্ডিলটি পুনরায় সংকলন করবে। এটি এড়াতে আপনার বিভিন্ন প্রধান প্রক্রিয়াতে আপনার মূল সার্ভার এবং ওয়েবপ্যাক সার্ভারটি চালানো উচিত যাতে পাইপিং কেবলমাত্র আপনার এক্সপ্রেস সার্ভার পুনরায় চালু করতে পারে এবং ওয়েবপ্যাকটি স্পর্শ না করে। আপনি concurrentlyপ্যাকেজ দিয়ে এটি করতে পারেন । প্রতিক্রিয়া-আইসোমরফিক-স্টার্টারকিটটিতে আপনি এর উদাহরণ খুঁজে পেতে পারেন । ইন package.json তিনি রয়েছে:

"scripts": {
    ...
    "watch": "node ./node_modules/concurrently/src/main.js --kill-others 'npm run watch-client' 'npm run start'"
  },

যা একই সাথে তবে পৃথক প্রক্রিয়াতে উভয় সার্ভার চালায়।


এর অর্থ কি কিছু ফাইল দু'বার দেখা হচ্ছে? যেমন ভাগ করা isomorphic / সর্বজনীন ফাইল?
ডেভিড সিনক্লেয়ার

1

historyApiFallback রুটগুলি সমেত একটি বুলিয়ানের পরিবর্তে কোনও বস্তুও হতে পারে।

historyApiFallback: navData && {
  rewrites: [
      { from: /route-1-regex/, to: 'route-1-example.html' }
  ]
}


-1

এটি আমার পক্ষে কাজ করেছে: কেবলমাত্র প্রথমে ওয়েবপ্যাক মিডলওয়্যারগুলি এবং সূচক html app.get('*'...সমাধানকারী পরে যুক্ত করুন,

তাই এক্সপ্রেসটি প্রথমে পরীক্ষা করে নেবে কিনা অনুরোধটি ওয়েবপ্যাকের সরবরাহিত কোনও রুটের সাথে মেলে (যেমন: /dist/bundle.jsবা /__webpack_hmr_) এবং যদি তা না হয়, তবে এটি এর index.htmlসাথে চলে যাবে* সমাধানকারীটির ।

অর্থাৎ,

app.use(require('webpack-dev-middleware')(compiler, {
  publicPath: webpackConfig.output.publicPath,
}))
app.use(require('webpack-hot-middleware')(compiler))
app.get('*', function(req, res) {
  sendSomeHtml(res)
})
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.