English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

webpackを使用してマルチページアプリケーションを構築する詳細な説明

Webpackの設定と使用について、オンラインには多くの記事がありますが、ほとんどがシングルページアプリケーションについてです。複数のhtmlをパッケージする必要がある場合、問題が複雑になります。どうやってwebpackで-dev-server内でルートを使用?複数のhtmlとjs chunkをどうやってパッケージし、mdを自動的に更新するか5?この記事では、これらの問題をどのように解決するかについて説明します。

ここでは、Webpackについて基本的な知識があると仮定しています

要件

私たちの要件を見てみましょう:

  1. webpackを使用-dev-開発時のサーバーとしてserverを使用
  2. webpack-dev-server内でルートを使用し、アクセス/aの時にa.htmlを表示、/bがb.htmlを表示
  3. 複数のhtmlにパッケージし、リソースを参照する箇所にmdを追加5タップ

主要ディレクトリ構造

├── src            
│  └── views         # それぞれのフォルダーに対応するページ
│    └── a         
│      └── index.js
│    └── b         
│      └── index.js
├── output          # 出力パッケージのディレクトリ
|  └── ...
└── template.html       # 各ページのhtmlをこのテンプレートに基に生成します
└── webpack.config.js
└── dev-server.js       # webpack-dev-server + express    

主要なディレクトリのみをリストアップしています。ここでは、template.htmlを基に複数のページのhtmlを生成しますが、それぞれのhtmlにはリソースのパスが異なります。もちろん、各ページごとに個別のhtmlテンプレートを使用することもできます。

Webpack 設定

ここでは2つの小さな問題を解決しています

1複数のページのjsファイルをパッケージします

srcを読み取ります/viewsのフォルダーは、各フォルダーをページとして、各ページを1つのjs chunkにパッケージします

2複数のhtmlをパッケージします

複数のHtmlWebpackPluginプラグインをループ生成し、各プラグインのchunksを上記のパッケージしたjs chunkにそれぞれ指します。

// webpack.config.js
var glob = require('glob');
var webpackConfig = {
  /* webpackの基本的な設定 */  
};
// 指定されたパスのエントリーファイルを取得します
function getEntries(globPath) {
   var files = glob.sync(globPath),
    entries = {};
   files.forEach(function(filepath) {
     // 取倒数第二層(viewの下のフォルダ)をパッケージ名にします
     var split = filepath.split('/');
     var name = split[split.length - 2];
     entries[name] = '.',/' + filepath;
   });
   return entries;
}
var entries = getEntries('src/view/**/index.js');
Object.keys(entries).forEach(function(name) {
  // 各ページにentryを生成し、HotUpdateが必要な場合はここでentryを修正します
  webpackConfig.entry[name] = entries[name];
  // 各ページにhtmlを生成します
  var plugin = new HtmlWebpackPlugin({
    // 生成されたhtmlファイル名
    filename: name + '.html',
    // 每个html的模版,这里多个页面使用同一个模版
    template: './template.html',
    // 自动将引用插入html
    inject: true,
    // 每个html引用的js模块,也可以在这里加上vendor等公用模块
    chunks: [name]
  });
  webpackConfig.plugins.push(plugin);
}

路由配置

在多页应用下,我们希望访问的是localhost:8080/a,而不是localhost:8080/a.html。

由于webpack-dev-server只是将文件打包在内存里,所以你没法在express里直接sendfile('output/views/a.html'),因为这个文件实际上还不存在。还好webpack提供了一个outputFileStream,用来输出其内存里的文件,我们可以利用它来做路由。

注意,为了自定义路由,你可能需要引进express或koa之类的库,然后将webpack-dev-server作为中间件处理。

// dev-server.js
var express = require('express')
var webpack = require('webpack')
var webpackConfig = require('./webpack.config')
var app = express();
// webpack编译器
var compiler = webpack(webpackConfig);
// webpack-dev-server中间件
-dev-middleware
  publicPath: webpackConfig.output.publicPath,
  stats: {
    colors: true,
    chunks: false
  }
});
app.use(devMiddleware)
// ルート
app.get('/:viewname? function(req, res, next) {
  var viewname = req.params.viewname 
    ? req.params.viewname + '.html' 
    : 'index.html';
  var filepath = path.join(compiler.outputPath, viewname);
  // webpackが提供するoutputFileSystemを使用します
  compiler.outputFileSystem.readFile(filepath, function(err, result) {
    if (err) {
      // something error
      return next(err);
    }
    res.set('content-type', 'text/html');
    res.send(result);
    res.end();
  });
});
module.exports = app.listen(8080, function(err) {
  if (err) {
    // do something
    return;
  }
  console.log('Listening at http://localhost: + port + '\n')
}

最後に、package.jsonで起動コマンドを定義します:

// package.json
{
  scripts: {
    "dev": "node ./dev-server.js"  
  }
}

npm run devを実行し、ブラウザでlocalhost:にアクセスしてください。8080/各ページで、あなたが望む結果が表示されるべきです。

これで本文のすべてが終わりです。皆様の学習に役立つことを願っています。また、ナイアラガイドを多くの皆様にサポートしていただけると嬉しいです。

声明:本文の内容はインターネットから取得しており、著作権者はすべて所有しています。インターネットユーザーが自発的に提供し、自己でアップロードしています。本サイトは所有権を持ちません。また、人工的な編集は行われていません。著作権侵害を疑われる内容がある場合は、メールでnotice#wまでお知らせください。3codebox.com(メールを送信する際、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認が取れましたら、本サイトは即座に侵害を疑われるコンテンツを削除します。)

おすすめ