Pertanyaan Buat bundel SPA individu dengan Webpack


Bagaimana cara menggunakan Webpack untuk membuat kumpulan SPA independen yang mungkin atau mungkin tidak dimuat dengan cepat saat pengguna saya menavigasi SPA saya?

Saya memiliki modul kontak, dan modul tugas. Keduanya memiliki dua dependensi. Saya ingin WebPack membuat bundel untuk masing-masing yang dimuat saat (dan jika) diperlukan.

Kode di bawah. Masalahnya tampaknya bahwa masing-masing entri ini dilihat sebagai titik masuk aplikasi, dan begitu juga mendapatkan kode bootstrap webpack dimasukkan di dalamnya.

Saya telah melihat berbagai contoh dengan CommonsChunkPlugin tetapi saya tidak dapat menemukan referensi / dokumentasi API untuk itu, dan dari apa yang dapat saya duga, bukan itu yang saya inginkan.

Sunting - temukan dokumen tersebut sini, dan menambahkan upaya dengan plugin di bawah ini dalam pengeditan saya.


Konfigurasi saat ini

module.exports = {
    entry: {
        contacts: './contacts',
        tasks: './tasks'
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name]-bundle.js'
    }
};

Contacts.js

define(['./ca', './cb'], function(ca, cb){
    var name = 'Contacts';
    alert(ca + ' ' + cb);
});

Tasks.js

define(['./ta', './tb'], function(ta, tb){
    var name = 'TASKS Main';
    alert(ta + ' ' + tb);
});

tasks-bundle.js

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};

/******/    // The require function
/******/    function __webpack_require__(moduleId) {

/******/        // Check if module is in cache
/******/        if(installedModules[moduleId])
/******/            return installedModules[moduleId].exports;

/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            exports: {},
/******/            id: moduleId,
/******/            loaded: false
/******/        };

/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/        // Flag the module as loaded
/******/        module.loaded = true;

/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }


/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;

/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;

/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";

/******/    // Load entry module and return exports
/******/    return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(3), __webpack_require__(4)], __WEBPACK_AMD_DEFINE_RESULT__ = function(ta, tb){
        var name = 'TASKS Main';
        alert(ta + ' ' + tb);
    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));

/***/ },
/* 1 */,
/* 2 */,
/* 3 */
/***/ function(module, exports, __webpack_require__) {

    var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function(){
        var name = 'TASKS - A';
        alert('ta');
    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));

/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {

    var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function(){
        var name = 'TASKS - B';
        alert('tb');
    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));

/***/ }
/******/ ]);

EDIT

Inilah upaya saya nomor 2 dengan CommonsChunkPlugin. Saya membuat aplikasi.js dummy

app.js

var module = window.location.hash.split('/')[0];
alert(module);

Lalu saya memindahkan semua file kontak dan tugas saya di bawah folder komponen, tetapi jika tidak membiarkannya. Konfigurasi baru saya:

module.exports = {
    entry: {
        app: './app'
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name]-bundle.js'
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: './components/contacts',
            filename: 'contacts-component-bundle.js'
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: './components/tasks',
            filename: 'tasks-component-bundle.js'
        })
    ]
};

Aneh sekali, sekarang app-bundle.js tampaknya tidak memiliki kode bootstrap Webpack apa pun

webpackJsonp([0,1,2],[
/* 0 */
/***/ function(module, exports) {

    var module = window.location.hash.split('/')[0];
    alert(module);

/***/ }
]);

kontak-komponen-bundle.js sekarang hanya punya ini

webpackJsonp([1,2],[]);

dan tugas-komponen-bundle.js tampaknya memiliki semua kode bootstrap webpack saya

/******/ (function(modules) { // webpackBootstrap
/******/    // install a JSONP callback for chunk loading
/******/    var parentJsonpFunction = window["webpackJsonp"];
/******/    window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {
/******/        // add "moreModules" to the modules object,
/******/        // then flag all "chunkIds" as loaded and fire callback
/******/        var moduleId, chunkId, i = 0, callbacks = [];
/******/        for(;i < chunkIds.length; i++) {
/******/            chunkId = chunkIds[i];
/******/            if(installedChunks[chunkId])
/******/                callbacks.push.apply(callbacks, installedChunks[chunkId]);
/******/            installedChunks[chunkId] = 0;
/******/        }
/******/        for(moduleId in moreModules) {
/******/            modules[moduleId] = moreModules[moduleId];
/******/        }
/******/        if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);
/******/        while(callbacks.length)
/******/            callbacks.shift().call(null, __webpack_require__);
/******/        if(moreModules[0]) {
/******/            installedModules[0] = 0;
/******/            return __webpack_require__(0);
/******/        }
/******/    };

/******/    // The module cache
/******/    var installedModules = {};

/******/    // object to store loaded and loading chunks
/******/    // "0" means "already loaded"
/******/    // Array means "loading", array contains callbacks
/******/    var installedChunks = {
/******/        2:0,
/******/        1:0
/******/    };

/******/    // The require function
/******/    function __webpack_require__(moduleId) {

/******/        // Check if module is in cache
/******/        if(installedModules[moduleId])
/******/            return installedModules[moduleId].exports;

/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            exports: {},
/******/            id: moduleId,
/******/            loaded: false
/******/        };

/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/        // Flag the module as loaded
/******/        module.loaded = true;

/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }

/******/    // This file contains only the entry chunk.
/******/    // The chunk loading function for additional chunks
/******/    __webpack_require__.e = function requireEnsure(chunkId, callback) {
/******/        // "0" is the signal for "already loaded"
/******/        if(installedChunks[chunkId] === 0)
/******/            return callback.call(null, __webpack_require__);

/******/        // an array means "currently loading".
/******/        if(installedChunks[chunkId] !== undefined) {
/******/            installedChunks[chunkId].push(callback);
/******/        } else {
/******/            // start chunk loading
/******/            installedChunks[chunkId] = [callback];
/******/            var head = document.getElementsByTagName('head')[0];
/******/            var script = document.createElement('script');
/******/            script.type = 'text/javascript';
/******/            script.charset = 'utf-8';
/******/            script.async = true;

/******/            script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"app","1":"./components/contacts"}[chunkId]||chunkId) + "-bundle.js";
/******/            head.appendChild(script);
/******/        }
/******/    };

/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;

/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;

/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/ })
/************************************************************************/
/******/ ([]);

Sekali lagi, saya hanya mencoba menggunakan Webpack untuk mendapatkan bukti SPA konsep dan berjalan, dengan semacam entry point root app.js, dan kemudian beberapa nomor sewenang-wenang modul / komponen yang dimuat pada permintaan. Ini sepele dengan persyaratan, jadi saya harus membayangkan saya kehilangan sesuatu kunci di sini, terutama dengan semua artikel yang pernah saya lihat tentang betapa hebatnya Webpack untuk SPAs.


EDIT 2

Jawaban Per bebraw di bawah ini saya coba yang berikut:

app.js

var mod = window.location.hash.split('/')[0];
alert(mod);

require.ensure([], function() {
    require('./components/' + mod).show();
});

webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: {
        app: './app'
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name]-bundle.js'
    }
};

Dan kemudian di folder build saya, saya pergi dengan app-bundle.js yang memiliki semua kode bootstrap saya, dan kode app.js saya, dan kemudian 1.1-bundle.js yang memiliki semua dari tugas dan kode kontak saya.

Saya sudah juga mencoba ini

module.exports = {
    entry: {
        app: './app'
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name]-bundle.js'
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: './components/contacts',
            filename: 'contacts-component-bundle.js',
            children: true
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: './components/tasks',
            filename: 'tasks-component-bundle.js',
            children: true
        })
    ]
};

Yang menghasilkan sama seperti di atas, tetapi sekarang juga memiliki tugas-komponen-bundle.js dan kontak-komponen-bundle.js, yang keduanya memiliki hanya beberapa kode bootstrap webpack; tugas dan kode kontak semuanya masih dalam 1,1-bundel.

Sekali lagi, saya hanya ingin dapat memberitahu Webpack, dengan satu atau lain cara, untuk menggabungkan modul individual dan dependensinya untuk kemalasan berikutnya, async loading saat diperlukan.

Jawaban terakhir diberikan oleh Tobias — pembuat Webpack — di bawah ini, yang akan saya tempatkan di sini untuk anak cucu.

Sesungguhnya dinamis tidak mungkin. webpack (dalam constract to require.js) mengkompilasi aplikasi Anda sebelum mengeksekusinya, dan tidak memiliki akses ke informasi runtime. Dinamis membutuhkan di webpack menyelam di setiap folder yang mungkin selama ekspresi dinamis Anda tidak mengandung ... Anda bahkan harus dapat mengkonfigurasinya untuk menggunakan mod + '/' + mod dengan ContextReplacementPlugin dan sedikit sihir RegExp (gunakan backreferences di RegExp). Secara default itu akan mencakup terlalu banyak modul.


32
2017-07-24 19:02


asal


Jawaban:


webpack membuat titik perpecahan per async membutuhkan pernyataan (require.ensure atau AMD require([])). Jadi, Anda perlu menulis a require([]) per bagian aplikasi Anda yang malas dimuat.

SPA Anda hanya memiliki satu titik masuk: router (sisi-klien). Sebut saja app.js. Halaman-halaman dimuat sesuai permintaan dan bukan merupakan titik masuk.

webpack.config.js:

module.exports = {
    entry: {
        app: './app'
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name]-bundle.js'
    }
}

app.js:

var mod = window.location.hash.split('/')[0].toLowerCase();
alert(mod);

switch(mod) {
    case "contacts":
        require(["./pages/contacts"], function(page) {
            // do something with "page"
        });
        break;
    case "tasks":
        require(["./pages/tasks"], function(page) {
            // do something with "page"
        });
        break;
}

Alternatif: Menggunakan "konteks".

Saat menggunakan ketergantungan dinamis i. e require("./pages/" + mod) Anda tidak dapat menulis titik perpecahan per file. Untuk kasus ini ada loader yang membungkus file dalam file require.ensure blok:

app.js

var mod = window.location.hash.split('/')[0].toLowerCase();
alert(mod);

require("bundle!./pages/" + mod)(function(page) {
    // do something with "page"
});

Ini khusus untuk webpack. Jangan lupa untuk npm install bundle-loader --save. Periksa casing yang benar, itu case-sensitive.


13
2017-07-28 08:06



Saya telah bekerja melalui sedikit ini dan ingin memposting pekerjaan saya di sini untuk kepentingan orang lain.

Premisnya adalah aplikasi web yang terdiri dari satu halaman, dengan utilitas kerangka tertentu yang dimuat awalnya, dengan semua bagian aplikasi yang dimuat saat diminta saat pengguna menavigasi dan mengubah url hash.

Bukti konsep app.js framework / entry point terlihat seperti ini

app.js

var framework = require('./framework/frameworkLoader');

window.onhashchange = hashChanged;
hashChanged(); //handle initial hash

function hashChanged() {
    var mod = window.location.hash.split('/')[0].replace('#', '');

    if (!mod) return;

    framework.loadModule(mod, moduleLoaded, invalidModule);

    function moduleLoaded(moduleClass, moduleHtml){
        //empty to remove handlers previously added
        $('#mainContent').empty();

        $('#mainContent').html(moduleHtml);

        var inst = new moduleClass();
        inst.initialize();
    }

    function invalidModule(){
        alert('Yo - invalid module');
    }
};

Tentunya tempat tujuan adalah framework.loadModule(mod, moduleLoaded, invalidModule);. Seperti yang dikatakan Tobias, harus ada gaya tersendiri yang terpisah, AMD membutuhkan pernyataan (saya percaya ada alternatif CommonJS, tetapi saya belum menjelajahinya) untuk SETIAP kemungkinan. Jelas tidak ada yang mau menulis setiap kemungkinan untuk aplikasi besar, jadi anggapan saya adalah bahwa semacam tugas simpul sederhana akan ada sebagai bagian dari proses membangun untuk menavigasi struktur aplikasi, dan otomatis menghasilkan semua ini memerlukan pernyataan untuk setiap modul untuk Anda. Dalam hal ini asumsinya adalah setiap folder dalam modules berisi modul, kode utama dan html yang berada dalam file yang diberi nama secara eponim. Misalnya, untuk kontak, definisi modul akan berada dalam modul / kontak / contacts.js dan html dalam modul / kontak / kontak.htm.

Saya hanya secara manual menulis file ini karena memiliki Node menavigasi folder dan struktur file, dan menghasilkan file baru sangatlah mudah.

frameworkLoader.js

//************** in real life this file would be auto-generated*******************

function loadModule(modName, cb, onErr){
    if (modName == 'contacts') require(['../modules/contacts/contacts', 'html!../modules/contacts/contacts.htm'], cb);
    else if (modName == 'tasks') require(['../modules/tasks/tasks', 'html!../modules/tasks/tasks.htm'], cb);
    else onErr();
}

module.exports = {
    loadModule: loadModule
};

Dengan sisa file:

webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: {
        app: './app'
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name]-bundle.js',
        publicPath: '/build/',
    }
};

Dan file html utama

default.htm

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>

        <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
        <script type="text/javascript" src="build/app-bundle.js"></script>
    </head>
    <body>
        <h1>Hello there!</h1>
        <h2>Sub heading</h2>

        <h3>Module content below</h3>
        <div id="mainContent"></div>
    </body>
</html>

Langkah selanjutnya adalah menambahkan dependensi ad hoc ke modul-modul ini. Sayangnya menambahkan require(['dep1', 'dep2'], function(){ tidak cukup berhasil seperti yang saya harapkan; yang dengan bersemangat mengejar semua dependensi dalam daftar, dan menggabungkan semuanya dengan modul yang dipermasalahkan, daripada memuatnya sesuai permintaan. Ini berarti bahwa jika kedua kontak dan modul tugas membutuhkan ketergantungan yang sama (karena mereka akan) kedua modul dengan memiliki seluruh dependensi yang dibundel, menyebabkannya dimuat dan dimuat ulang saat pengguna menelusuri ke kontak dan kemudian tugas.

Solusinya adalah bundel loader npm install bundle-loader --save. Ini memungkinkan kami melakukannya require('bundle!../../libs/alt') yang mengembalikan a fungsi bahwa ketika dipanggil menjemput ketergantungan kita. Fungsi mengambil argumen sebagai panggilan balik yang menerima ketergantungan baru kita. Jelas memuat dependensi N seperti ini akan membutuhkan kode yang tidak menyenangkan untuk mempermainkan callback N, jadi saya akan membangun dukungan Janji hanya dalam beberapa saat. Tapi pertama-tama untuk memperbarui struktur modul untuk mendukung spesifikasi ketergantungan.

contacts.js

function ContactsModule(){
    this.initialize = function(alt, makeFinalStore){
        //use module
    };
}

module.exports = {
    module: ContactsModule,
    deps: [require('bundle!../../libs/alt'), require('bundle!alt/utils/makeFinalStore')]
};

tasks.js

function TasksModule(){
    this.initialize = function(alt){
        //use module
    };
}

module.exports = {
    module: TasksModule,
    deps: [require('bundle!../../libs/alt')]
};

Sekarang setiap modul mengembalikan literal objek dengan modul itu sendiri, dan dependensi yang dibutuhkannya. Tentunya akan menyenangkan untuk hanya menulis daftar string, tetapi kita membutuhkan require('bundle! panggilan di sana sehingga Webpack dapat melihat apa yang kita butuhkan.

Sekarang untuk membangun dukungan Janji untuk app.js utama kami

app.js

var framework = require('./framework/frameworkLoader');

window.onhashchange = hashChanged;
hashChanged(); //handle initial hash

function hashChanged() {
    var mod = window.location.hash.split('/')[0].replace('#', '');

    if (!mod) return;

    framework.loadModule(mod, moduleLoaded, invalidModule);

    function moduleLoaded(modulePacket, moduleHtml){
        var ModuleClass = modulePacket.module,
            moduleDeps = modulePacket.deps;

        //empty to remove handlers previous module may have added
        $('#mainContent').empty();

        $('#mainContent').html(moduleHtml);

        Promise.all(moduleDeps.map(projectBundleToPromise)).then(function(deps){
            var inst = new ModuleClass();
            inst.initialize.apply(inst, deps);
        });

        function projectBundleToPromise(bundle){
            return new Promise(function(resolve){ bundle(resolve); });
        }
    }

    function invalidModule(){
        alert('Yo - invalid module');
    }
};

Ini menyebabkan file bundel individu terpisah dibuat untuk kontak, tugas, alt, dan makeFinalStore. Memuat tugas pertama menunjukkan bundel dengan modul tugas, dan bundel dengan pemuatan alt di tab jaringan; memuat kontak setelah itu menunjukkan pemuatan bundel kontak bersama dengan bundel makeFinalStore. Memuat kontak pertama menunjukkan kontak, alt, dan pemuatan bundel FunFore; memuat tugas setelah itu hanya menunjukkan tugas-tugas pemuatan bundel.


Terakhir, saya ingin memperluas modul kontak sehingga akan mendukung pemuatan dinamis ad hoc sendiri. Dalam kehidupan nyata, modul kontak mungkin memuat dengan cepat informasi penagihan kontak, informasi kontak, informasi berlangganan, dan sebagainya. Tentunya bukti konsep ini akan lebih sederhana, berbatasan dengan konyol.

Di bawah folder kontak saya membuat folder contactDynamic, dengan file-file berikut

contentA.js
contentA.htm
contentB.js
contentB.htm
contentC.js
contentC.htm

contentA.js

module.exports = {
    selector: '.aSel',
    onClick: function(){ alert('Hello from A') }
};

contentA.htm

<h1>Content A</h1>

<a class="aSel">Click me for a message</a>

contentB.js

module.exports = {
    selector: '.bSel',
    onClick: function(){ alert('Hello from B') }
};

contentB.htm

<h1>Content B</h1>

<a class="bSel">Click me for a message</a>

contentC.js

module.exports = {
    selector: '.cSel',
    onClick: function(){ alert('Hello from C') }
};

contentC.htm

<h1>Content C</h1>

<a class="cSel">Click me for a message</a>

Kode yang diperbarui untuk contacts.js ada di bawah. Beberapa hal yang perlu diperhatikan. Kami sedang membangun konteks dinamis sebelumnya sehingga kami dapat mengecualikan file dengan tepat. Jika tidak, maka dinamika kita membutuhkan dengan bundle! akan gagal ketika sampai ke file html; konteks kami membatasi file *.js. Kami juga membuat konteks untuk file .htm — perhatikan bahwa kami menggunakan keduanya bundle! dan html! loader bersama. Juga perhatikan itu memesan hal-hal - bundle!html! bekerja tetapi html!bundle! menyebabkan bundel ini tidak dibangun, dan saya berharap seseorang dapat berkomentar tentang mengapa. Tetapi sebagaimana adanya, bundel terpisah dibuat untuk setiap file .js, dan .htm, dan dimuat hanya bila dibutuhkan. Dan tentu saja saya membungkus bundle! panggilan dalam Janji seperti sebelumnya.

Juga, saya mengerti bahwa ContextReplacementPlugin dapat digunakan sebagai pengganti konteks ini, dan saya berharap seseorang dapat menunjukkan kepada saya bagaimana: adalah contoh dari ContextReplacementPlugin lulus menjadi dinamis require?

contacts.js

function ContactsModule(){
    this.initialize = function(alt, makeFinalStore){
        $('#contacts-content-loader').on('click', '.loader', function(){
            loadDynamicContactContent($(this).data('name'));
        });
    };
}

function loadDynamicContactContent(name){
    var reqJs = require.context('bundle!./contactDynamic', false, /.js$/);
    var reqHtml = require.context('bundle!html!./contactDynamic', false, /.htm$/);

    var deps = [reqJs('./' + name + '.js'), reqHtml('./' + name + '.htm')];

    Promise.all(deps.map(projectBundleToPromise)).then(function(deps){
        var code = deps[0],
            html = deps[1];

        $('#dynamicPane').empty().html(html);
        $('#dynamicPane').off().on('click', code.selector, function(){
            code.onClick();
        });
    });
}

function projectBundleToPromise(bundle){
    return new Promise(function(resolve){ bundle(resolve); });
}

module.exports = {
    module: ContactsModule,
    deps: [require('bundle!../../libs/alt'), require('bundle!alt/utils/makeFinalStore')]
};

contacts.htm

<h1>CONTACTS MODULE</h1>

<div id="contacts-content-loader">
    <a class="loader" data-name="contentA">Load A</a>
    <a class="loader" data-name="contentB">Load B</a>
    <a class="loader" data-name="contentC">Load C</a>
</div>

<div id="dynamicPane">
    Nothing loaded yet
</div>

Terakhir, default.htm terakhir

default.htm

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>

        <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
        <script type="text/javascript" src="build/app-bundle.js"></script>
    </head>
    <body>
        <h1>Hello there!</h1>
        <h2>Sub heading</h2>

        <a href="#contacts">Load contacts</a>
        <br><br>
        <a href="#tasks">Load tasks</a>

        <h3>Module content below</h3>
        <div id="mainContent"></div>
    </body>
</html>

4
2017-08-07 18:54



kupikir require.ensure mungkin kunci di sini. Itu akan memungkinkan Anda untuk mengatur poin terpisah untuk pemuatan dinamis. Anda akan menghubungkannya dengan router SPA Anda dalam beberapa cara. Inilah ide dasar dari Pete Hunt: https://github.com/petehunt/webpack-howto#9-async-loading .


0
2017-07-27 06:09