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

webpackの詳細+expressによるマルチページサイトの開発

webpackの上級のチュートリアルを学んだ後、特にシングルページアプリケーションに特化していると感じました、例えばwebpack+react、webpack+vueなど、さまざまなリソースの依存関係のロード、パッキングの問題を解決できます。また、cssもjsにパッキングして動的にdomドキュメントに追加されます。

それでは、もし複数ページの一般的なwebサイトで、cssを独立させ、jsのロードにはモジュールが必要な場合、どうですか?

プロジェクトのアドレス:webpackDemo_jb51.rar

プロジェクトの初期化、依存関係のインストール

package.json

"devDependencies": {
  "css-loader": "^0.23.1",
  "extract-text-webpack-plugin": "^1.0.1",
  "file-loader": "^0.8.5",
  "html-loader": "^0.4.3",
  "html-webpack-plugin": "^2.9.0",
  "jquery": "^1.12.0",
  "less": "^2.6.0",
  "less-loader": "^2.2.2",
  "sass-loader": "^4.0.2",
  "style-loader": "^0.13.0",
  "url-loader": "^0.5.7",
  "webpack": "^1.12.13",
  "webpack-dev-server": "^1.14.1"
}

ディレクトリ構造(私はexpressフレームワークを使用していますが、他は個人の要件に応じて)

- webpackDemo
  - src        #コード開発ディレクトリ
    - css      #cssディレクトリ、ページ(モジュール)、一般的、サードパーティー三个レベルで構成
      + page
      + common
      + lib
    - js       #JSスクリプト、page、componentsに基づいて構成
      + page
      + components
    + template      #HTMLテンプレート
  - node_modules    #使用しているnodejsモジュール
  - public            #express静的リソースファイル
    - dist            #webpackコンパイルパック出力ディレクトリ、ディレクトリを作成する必要はなくwebpackが設定に基づいて自動的に生成します
      + css        
      + js
    + img      #画像リソース
  + view            #express静的リソースファイル(webpackコンパイルパック出力viewディレクトリ)
  package.json      #プロジェクト設定
  webpack.config.js  #webpack設定

ページ開発

src/js/pageディレクトリにindex.jsファイルを作成します、src/viewディレクトリにindex.htmlファイルを作成します。エントリージェスファイルとテンプレートファイルの名前が対応しています。

index.htmlの内容は以下の通りです:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8>
  <title>ホーム</title>
  <!--
    説明:headにはCSSやfaciconをインクルードする必要はありません、webpackはエントリージェスファイルの要求に基づいて自動的に必要に応じてロードしたり、styleタグを作成します
  -->
</head>
<body>
  <!--
    説明:bodyには別々にJSファイルをインクルードする必要はありません、webpackはエントリージェスファイルに基づいて自動的に必要に応じてロードしたり、scriptタグを作成したり、対応するhash値を作成します
  -->
</body>
</html>

これがシンプルなHTMLテンプレートであり、CSSやJSをインクルードすることなく、webpackでパッケージ化することで自動的にインクルードされます。

index.jsの内容は以下の通りです:

//CSSをインクルードします
require("../../css/lib/base.css");
require("../../css/page/index.scss");
$('body').append('<p class="text">index</p>');

page1.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8>
  <title>page1</title>
</head>
<body>
</body>
</html>

page1.js:

//CSSをインクルードします
require("../../css/lib/base.css");
require("../../css/page/page1.less");
$('body').html('page1');

webpackの設定(私はexpressフレームワークを使用していますが、他のフレームワークは個々のニーズに応じて設定してください)

var path = require('path');
var webpack = require('webpack');
/*
extract-text-webpack-pluginプラグイン、
これにより、スタイルを独立したcssファイルに抽出することができます。
ママはもはやスタイルがjsファイルにパックされることを心配しなくても大丈夫です。
 */
var ExtractTextPlugin = require('extract-text-webpack-plugin');
/*
html-webpack-pluginプラグイン、非常に重要なプラグイン、webpackでHTMLを生成するプラグイン、
詳細はこちらを参照してくださいhttps://www.npmjs.com/package/html-webpack-plugin
 */
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  entry: { //エントリーファイルを設定します、いくつかある場合はすべて設定してください
    index: './src/js/page/index.js',
    page1: './src/js/page/page1.js'
  },
  output: { 
    path: path.join(__dirname, './public/dist/'), //出力ディレクトリの設定、テンプレート、スタイル、スクリプト、画像などのリソースのパス設定はそれに相対的
    publicPath: '/dist/',        //テンプレート、スタイル、スクリプト、画像などのリソースが対応するサーバー上のパス
    filename: 'js/[name].js',      //各ページに対応するメインJSの生成設定
    chunkFilename: 'js/[id].chunk.js'  //チャンク生成の設定
  },
  module: {
    loaders: [ //各ロードアシスタントのパラメータ設定については、Googleで検索してください。
      {
        test: /.css$/,
        //cssの抽出器、ロードアシスタントを設定します。-loader'は省略できます
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader) 
      
        test: /.less$/,
        //lessの抽出器、ロードアシスタントを設定します。中間の!が説明が必要です。
        //右から左に向かって順にless、cssロードアシスタントを呼び出し、前のアシスタントの出力が次のアシスタントの入力になります
        //あなた自身のloaderを開発することもできます。loaderの書き方については、Googleで検索してください。
        loader: ExtractTextPlugin.extract('css!less')
      
        test: /\.scss$/,
        //scssの抽出器、ロードアシスタントを設定します。中間の!が説明が必要です。
        //右から左に向かって順にscss、cssロードアシスタントを呼び出し、前のアシスタントの出力が次のアシスタントの入力になります
        //あなた自身のloaderを開発することもできます。loaderの書き方については、Googleで検索してください。
        loader: ExtractTextPlugin.extract('css!scss')
      
        //HTMLテンプレートロードアシスタント、参照された静的リソースを処理できる、デフォルトの設定パラメータattrs=img:src、画像のsrc参照のリソースを処理
        //例えば、以下のように設定すると、attrs=img:src img:data-srcを使用してdataも一括で処理できます-srcにリファレンスされたリソースを、以下のように
        test: /.html$/,
        loader: "html?attrs=img:src img:data-src"
      
        //ファイルローダー、静的リソースを処理します
        test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9])\.[0-9])\.[0-9))?$/,
        loader: 'file-loader?name=./fonts/[name].[ext]
      
        //画像ローダー、fileと同様-loader、画像用に適しています。小さな画像をbaseに変換できます64、HTTPリクエストを減少させます
        //以下の設定では、以下のサイズの画像を8192バイトの画像をbaseに変換します64の
        test: /\.(png|jpg|gif)$/,
        loader: 'url-loader?limit=8192&name=./img/[hash].[ext]'
      }
    }],
  },
  plugins: [
    new webpack.ProvidePlugin({ //jqをロードする
      $: 'jquery'
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'commons', // 公共モジュールを抽出し、`commons`というchunkを生成します
      chunks: ['index','page1], //共有するモジュールのどの部分を抽出するか
      minChunks: 2 // 少なくとも2個のモジュールが共有する部分
    }),
    new ExtractTextPlugin('css/[name].css'), //linkタグを使用してCSSを単独でロードし、パスを設定します。output設定のpublickPathの相対パス
    //HtmlWebpackPluginのテンプレート生成に関する設定です。各設定は各ページの設定に対応しており、必要な分だけ記述します
    new HtmlWebpackPlugin({ //テンプレートにcssを挿入します/jsなどの最終HTMLを生成します
      favicon: '.',/src/favicon.ico', //favicon パス、webpack でインポートし、ハッシュ値を生成できます
      filename: '../../views/index.html', //生成されたHTMLが保存されるパス、pathの相対パス
      template: '.',/src/template/index.html', //htmlテンプレートのパス
      inject: 'body', //jsを挿入する場所、true/'head'/'body'/false
      hash: true, //静的リソースにハッシュ値を生成します
      chunks: ['commons', 'index'],//必要なchunkを指定します。設定しなければすべてのページのリソースが読み込まれます
      minify: { //HTMLファイルを圧縮する  
        removeComments: true, //HTML中のコメントを削除する
        collapseWhitespace: false //スペースと改行符を削除する
      }
    }),
    new HtmlWebpackPlugin({ //テンプレートにcssを挿入します/jsなどの最終HTMLを生成します
      favicon: '.',/src/favicon.ico', //favicon パス、webpack でインポートし、ハッシュ値を生成できます
      filename: '../../views/page1.html', //生成されたHTMLが保存されるパス、pathの相対パス
      template: '.',/src/template/page1.html', //htmlテンプレートのパス
      inject: true, //jsを挿入する場所、true/'head'/'body'/false
      hash: true, //静的リソースにハッシュ値を生成します
      chunks: ['commons', 'list'],//必要なchunkを指定します。設定しなければすべてのページのリソースが読み込まれます
      minify: { //HTMLファイルを圧縮する  
        removeComments: true, //HTML中のコメントを削除する
        collapseWhitespace: false //スペースと改行符を削除する
      }
    }
    // new webpack.HotModuleReplacementPlugin(), //ホットロード
  ],
  //webpackを使用します-dev-serverを利用して開発効率を向上させます
  // devServer: {
  //   contentBase: '.',/',
  //   host: 'localhost',
  //   port: 9090, //デフォルト8080
  //   inline: true, //jsの変更を監視できます
  //   hot: true, //ホットスタート
  // }
};

もう、以上の設定を完了したら、webpackパッケージ命令を実行してプロジェクトのパッケージを完了します。

Hash: e6219853995506fd132a
Version: webpack 1.14.0
Time: 1338ms
        Asset Size Chunks Chunk Names
     js/index.js 457 bytes    0 [emitted] index
     js/page1.js 392 bytes    1 [emitted] page1
    js/commons.js   306 kB    2 [emitted] commons
    css/index.css  62 bytes    0 [emitted] index
    css/page1.css  62 bytes    1 [emitted] page1
   css/commons.css 803 bytes    2 [emitted] commons
     favicon.ico  1.15 kB     [emitted]
../../view/index.html 496 bytes     [emitted]
../../view/page1.html 499 bytes     [emitted]
  [0] ./src/js/page/index.js 170 bytes {0} [built]
  [0] ./src/js/page/page1.js 106 bytes {1} [built]
  + 7 hidden modules
Child html-webpack-plugin for "../../view/page1.html":
    + 1 hidden modules
Child html-webpack-plugin for "../../view/index.html":
    + 1 hidden modules
Child extract-text-webpack-plugin:
    + 2 hidden modules
Child extract-text-webpack-plugin:
    + 2 hidden modules
Child extract-text-webpack-plugin:
    + 2 hidden modules

この時、viewsディレクトリに移動して生成されたindex.htmlファイルを確認してください、以下のようになります:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8>
  <title>ホーム</title>  
<link rel="shortcut icon" href="/dist/favicon.ico" rel="external nofollow" ><link href="/dist/css/commons.css?e6219853995506fd132a" rel="external nofollow" rel="stylesheet"><link href="/dist/css/index.css?e6219853995506fd132a" rel="external nofollow" rel="stylesheet"></head>
<body>
  <script type="text/javascript" src="/dist/js/commons.js?e6219853995506fd132a"></script><script type="text/javascript" src="/dist/js/index.js?e6219853995506fd132a"></script></body>
</html>

生成されたファイルは、元のテンプレートの内容を保持しただけでなく、エントリーファイルindex.jsの定義に基づいて、必要なCSSとJSファイル、およびfaviconを自動的に追加し、さらに対応するhash値も追加されます。

二つの問題があります

  1. webpackがentryファイルを自動で検出し、相应的なテンプレート設定を行う方法について
  2. スタイルやスクリプトの自動インクルード問題を直接どう処理するか
var path = require('path');
var webpack = require('webpack');
var glob = require('glob');
/*
extract-text-webpack-pluginプラグイン、
これにより、スタイルを独立したcssファイルに抽出することができます。
ママはもはやスタイルがjsファイルにパックされることを心配しなくても大丈夫です。
 */
var ExtractTextPlugin = require('extract-text-webpack-plugin');
/*
html-webpack-pluginプラグイン、非常に重要なプラグイン、webpackでHTMLを生成するプラグイン、
詳細はこちらを参照してくださいhttps://www.npmjs.com/package/html-webpack-plugin
 */
var HtmlWebpackPlugin = require('html-webpack-plugin');
/**
 *公共モジュールを抽出し、`commons`というchunkを生成します
 */
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
//圧縮
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
//開発モードの判定
var debug = process.env.NODE_ENV !== 'production';
var getEntry = function(globPath, pathDir) {
  var files = glob.sync(globPath);
  var entries = {},
    entry, dirname, basename, pathname, extname;
  for (var i = 0; i < files.length; i++) {
    entry = files[i];
    dirname = path.dirname(entry);  //ファイルディレクトリ
    extname = path.extname(entry);  //拡張子名
    basename = path.basename(entry, extname); //ファイル名
    pathname = path.join(dirname, basename);
    pathname = pathDir ? pathname.replace(new RegExp('^', + pathDir, '') : pathname;
    entries[pathname] = ['./' + entry]; //これはosxシステム下での書き方です win7 entries[basename]
  }
  console.log(entries);
  return entries;
}
//エントリ(すべてのページエントリをgetEntryメソッドで取得)
var entries = getEntry('src/js/page/**/*.js', 'src/js/page/');
//何のモジュールが共有部分を持つかを抽出するためにentriesからファイル名を取得
var chunks = Object.keys(entries);
//テンプレートページ(すべてのテンプレートページをgetEntryメソッドで取得)
var pages = Object.keys(getEntry('src/template/**/*.html', 'src/template/'));
console.log(pages)
var config = {
  entry: entries,
  output: {
    path: path.join(__dirname, './public/dist/'),//出力ディレクトリの設定、テンプレート、スタイル、スクリプト、画像などのリソースのパス設定はそれに相対的
    publicPath: '/dist/',        //テンプレート、スタイル、スクリプト、画像などのリソースが対応するサーバー上のパス
    filename: 'js/[name].js',      //各ページに対応するメインJSの生成設定
    chunkFilename: 'js/[id].chunk.js?[chunkhash]'  //チャンク生成の設定
  },
  module: {
    loaders: [ //ローダー
      {
        test: /.css$/,
        loader: ExtractTextPlugin.extract('style', 'css')
      
        test: /.less$/,
        loader: ExtractTextPlugin.extract('css!less')
      
        test: /.html$/,
        loader: "html?-minimize"  //避け圧縮html,https://github.com/webpack/html-loader/issues/50
      
        test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9])\.[0-9])\.[0-9))?$/,
        loader: 'file-loader?name=fonts/[name].[ext]
      
        test: /\.(png|jpe?g|gif)$/,
        loader: 'url-loader?limit=8192&name=imgs/[name]-[hash].[ext]'
      }
    }],
  },
  plugins: [
    new webpack.ProvidePlugin({ //jqをロードする
      $: 'jquery'
    }),
    new CommonsChunkPlugin({
      name: 'commons', // 公共モジュールを抽出し、`commons`というchunkを生成します
      chunks: chunks,
      minChunks: chunks.length // すべてのentryが共有するモジュールを抽出する
    }),
    new ExtractTextPlugin('css/[name].css'), //linkタグを使用してCSSを単独でロードし、パスを設定します。output設定のpublickPathの相対パス
    debug ? function() {} : new UglifyJsPlugin({ //コードを圧縮する
      compress: {
        warnings: false
      },
      except: ['$super', '$', 'exports', 'require'] //除外するキーワード
    }),
  }],
};
pages.forEach(function(pathname) {
  var conf = {
    filename: '../../views/' + pathname + '.html', //生成されたHTMLが保存されるパス、pathの相対パス
    template: 'src/template/' + pathname + '.html', //htmlテンプレートのパス
    inject: false, //jsを挿入する場所、true/'head'/'body'/false
    /*
    * この圧縮部分では、html-minify、圧縮時に多くのHTML構文チェック問題が発生します。
    * HTMLタグ属性に{{...}}表現を使用している場合、多くの場合この設定での圧縮項目は必要ありません。
    * また、UglifyJsPluginはコードを圧縮する際にHTMLも同時に圧縮します。
    * HTMLを圧縮しないようにするには、html-loader上に'html?-minimize'、loadersのhtmlに見てください-loaderの設定。
     */
    // minify: { //HTMLファイルを圧縮する
    // removeComments: true, //HTML中のコメントを削除する
    // collapseWhitespace: false //スペースと改行符を削除する
    // }
  };
  if (pathname in config.entry) {
    favicon: '.',/src/favicon.ico', //favicon パス、webpack でインポートし、ハッシュ値を生成できます
    conf.inject = 'body';
    conf.chunks = ['commons', pathname];
    conf.hash = true;
  }
  config.plugins.push(new HtmlWebpackPlugin(conf));
});
module.exports = config;  

以下のコードは上記のものと似ていますが、基本的な違いは、すべての関連ファイルをオブジェクトに格納する方法で自動ロード効果を達成することです!

これらはすべて mac osx システムの設定であり、win7パスが異なる可能性があります

glob: ここで解析されたものが異なります:

ただし、最終

entries:
 {
 index: ['./src/template/index.js'],
 page1: ['./src/template/page1.js']
 }
pages:
 ['index', 'page'1']'

パーソナル コンピュータの構成に応じて変更してください

これでこの記事は全てです。皆さんの学習に役立てば幸いですし、もっと「ノートルーチン」教程をサポートしていただけると嬉しいです。

声明:この記事の内容はインターネットから取得しており、著作権者はすべて権利を保有しています。コンテンツはインターネットユーザーによって自発的に貢献し、アップロードされています。このサイトは所有権を持ちませんし、編集もされていません。著作権侵害が疑われる内容を見つけた場合は、以下のメールアドレスにご連絡ください:notice#oldtoolbag.com(メールを送信する際、#を@に変更してください)で通報し、関連する証拠を提供してください。一旦確認がとれましたら、このサイトは即座に侵害する可能性のあるコンテンツを削除します。

基本教程
おすすめ