多数の記事(たとえば、 この記事)を読んだ後、「恐竜」アプローチを使用して単純なサイトを作成するときに、Node.jsを使用した最新のアプローチに切り替えることにしました。 以下は、 Webpack 4を使用して単純な静的サイトを構築する解析例です。 問題を解決するための指示が見つからなかったため、この記事は書かれました。すべてを断片的に収集しなければなりませんでした。
問題の声明
サイトは、独自のCSSスタイルとJavaScriptファイルを備えたHTMLページの単純なセットです。 サイトをソースから組み立てるプロジェクトを作成する必要があります。
- SASS(より正確にはSCSS)ファイルから、1つのCSSファイルが形成されます。
- さまざまなJavaScriptライブラリとユーザーコードから1つのJavaScriptファイルが形成されます。
- HTMLページはテンプレートエンジンを使用して組み立てられます。テンプレートエンジンでは、ヘッダーとフッターのコンテンツを個別のファイルに分割できます。
組み立てられたサイトでは、React、Vue.jsを使用しないでください。
テクノロジーを選択するとき、現時点で最も人気のあるものが選択されます。 このため、私はGruntとGulpの両方をWebpackに賛成して拒否しましたが、正直なところ、単調さのためにGulp構文がより好きでした。
たとえば、Bootstrap 4に基づく複数のページがコンパイルされますが、これは単なる例です。
Node.jsがインストールされていると想定され(Windowsでは、インストーラーは「次、次」のスタイルでダウンロードおよびインストールされるだけです)、コマンドラインで作業できます。
更新する 追加の設定なしで(GitHubページなどで)ホスティングにアップロードするか、コンピューターでローカルに開くことができる既製のHTMLページのセットを取得する必要があります。
プロジェクト構造
プロジェクトの一般的な構造は次のとおりです。
. ├── dist - , ├─┬ src - │ ├── favicon - │ ├── fonts - │ ├─┬ html - HTML │ │ ├── includes - (header, footer) │ │ └── views - HTML │ ├── img - (, .) │ ├── js - JavaScript │ ├── scss - SSS │ └── uploads - (, .) ├── package.json - Node.js └── webpack.config.js - Webpack
. ├── dist ├─┬ src │ ├─┬ favicon │ │ └── favicon.ico │ ├─┬ fonts │ │ └── Roboto-Regular.ttf │ ├─┬ html │ │ ├─┬ includes │ │ │ ├── footer.html │ │ │ └── header.html │ │ └─┬ views │ │ ├── index.html │ │ └── second.html │ ├─┬ img │ │ └── logo.svg │ ├─┬ js │ │ └── index.js │ ├─┬ scss │ │ └── style.scss │ └─┬ uploads │ └── test.jpg ├── package.json └── webpack.config.js
ファビコンの下でフォルダ全体が選択されます。これは、最新のWebでは1つのicoファイルだけではできないためです。 しかし、たとえば、この単一のファイルのみが使用されます。
物議をかもす決定は、画像をimg
とuploads
2つのフォルダーに分割するように見えるかもしれません。 しかし、ここではWordpressのファイルレイアウトのイデオロギーを使用しました。 私の意見では、すべての画像を1つのフォルダーに入れることはお勧めできません。
このプロジェクトで作業するには、 Visual Studio Codeを使用します。 コマンドラインがプログラムに組み込まれ、 Ctrl + `を介して呼び出されることが特に気に入っています。
プロジェクトNode.jsを空白にします。 これを行うには、上記の構造を使用してプロジェクト用のフォルダーを作成し、コマンドラインでそのフォルダーに移動します。そこで、コマンドを呼び出してpackage.json
ファイルを作成します。
npm init
詳細な情報をEnter
たくない場合は、 Enter
を押すだけですべての質問に答えることができます。
いずれの場合でも必要になる3つの一般的なパッケージをインストールします: webpack
、 webpack-cli
( webpack-cli
のコマンドラインでの作業は別のパッケージに取り込まれました)およびwebpack-dev-server
(保存されたプロジェクトの変更がブラウザーにすぐに表示されるようにローカルサーバーを起動するため) 。
npm install webpack webpack-cli webpack-dev-server --save-dev
{ "name": "static-site-webpack-habr", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "license": "ISC", "devDependencies": { "webpack": "^4.1.1", "webpack-cli": "^2.0.11", "webpack-dev-server": "^3.1.1" } }
package-lock.json
ファイルも作成されますが、これには一切触れません。 ただし、gitリポジトリでは、 node_modules
フォルダーとは異なり、このファイルを追加する必要がありますnode_modules
フォルダーは、gitを使用する場合は.gitignore
ファイルに書き込む必要があります。
JavaScriptを構築する
Webpackは主にjsファイルを作成するために作成されているため、この部分が最も簡単です。 ブラウザでサポートされていないES2015の最新の形式でjavascriptを記述できるように、パッケージbabel-core
、 babel-loader
、 babel-preset-env
をインストールします。
npm install babel-core babel-loader babel-preset-env --save-dev
次の内容でwebpack.config.js
設定webpack.config.js
を作成した後:
const path = require('path'); module.exports = { entry: [ './src/js/index.js', ], output: { filename: './js/bundle.js' }, devtool: "source-map", module: { rules: [{ test: /\.js$/, include: path.resolve(__dirname, 'src/js'), use: { loader: 'babel-loader', options: { presets: 'env' } } }, ] }, plugins: [ ] };
entry
セクション( entry
ポイント)では、収集するjsファイルを示し、 output
セクションでは、収集したファイルが配置されるdist
フォルダのパスを示します。 output
パスのwebpack 4では、 dist
フォルダー自体を指定する必要がないことに注意してください! そして、はい、私はそれを1つのwebpackファイルで好きではない場合は、相対パスを書く必要がある場合があり、他の場合は特別なフォルダーに相対パスを書く必要があり、3番目の場合は絶対パスが必要です(たとえば、このコマンドpath.resolve(__dirname, 'src/js')
それを取得します。 path.resolve(__dirname, 'src/js')
)。
また、 devtool
パラメーター値はsource-map
等しく設定されsource-map
。これにより、jsおよびcssファイルのソースマップを作成できます。
特定のファイル(拡張子、場所)を処理するには、webpackのrules
セクションにルールを作成しrules
。 ここで、すべてのjsファイルをBabelトランスレータに渡すというルールがあります。Babelトランスレータは、新しく作成されたES2015をブラウザが理解できる標準のjavascriptバージョンに変換します。
テストケースでは、Boostrap 4にページを課しています。したがって、 bootstrap
、 jquery
、 popper.js
3つのパッケージをインストールする必要があります。 ブートストラップでオンデマンドでインストールする2番目と3番目のパッケージ。
npm install bootstrap jquery popper.js --save
これらの3つのパッケージは、サイトではなく、アセンブリ用に必要であることに注意してください。 したがって、これらのパッケージは--save-dev
ではなく--save-dev
フラグでインストールします。
これで、 index.js
ファイルの作成を開始できます。
import jQuery from 'jquery'; import popper from 'popper.js'; import bootstrap from 'bootstrap'; jQuery(function() { jQuery('body').css('color', 'blue'); });
カスタムコードの例として、jsはテキストの色を青に塗り直しました。
これで、jsファイルのビルドに進むことができます。 これを行うには、 scripts
セクションのpackage.json
ファイルに、次のnpmスクリプトを記述します。
"scripts": { "dev": "webpack --mode development", "build": "webpack --mode production", "watch": "webpack --mode development --watch", "start": "webpack-dev-server --mode development --open" },
これで、コマンドラインでnpm run dev行を実行すると、プロジェクトがアセンブルされ(cssおよびhtmlファイルもこのコマンドによって収集されます)、 bundle.js
およびbundle.js.map
ファイルが/dist/js
bundle.js.map
。
npm run buildコマンドを実行すると、プロジェクトもアセンブルされますが、最終的なもの(最適化、最大ファイル最小化)はホスティングにアップロードできます。
npm run watchを開始すると、変更されたファイルが自動的に追加され、プロジェクトファイルへの変更を自動的に表示するモードが開始されます。 はい、コマンドラインでこのモードを無効にする(たとえば、他のコマンドを書く)には、 Ctrl + C
押します(少なくともPowerShellで)。
npm run startを起動すると、ローカルサーバーが起動し、htmlページが起動し、ファイルの変更も追跡されます。 ただし、現時点では、HTMLページのアセンブリが追加されていないため、このコマンドは使用していません。
プロジェクトビルドモードは、 dist
フォルダー内のファイルを作成または上書きします。 ただし、異なるアセンブリを使用したプロジェクトの開発中に、ファイルの名前を変更したり、削除したりできます。 また、Webpackは、以前のビルドで残った不要なファイルがdist
フォルダーから削除されることを保証しません。 したがって、各プロジェクトをビルドする前にdist
フォルダーをクリアする別のclean-webpack-plugin
を追加します。
2018.04.11。を更新 clean-webpack-plugin
を放棄しなければなりclean-webpack-plugin
。 なんで? npm run start
webpack-dev-server --mode development --open
( webpack-dev-server --mode development --open
)でwebpack-dev-server --mode development --open
、webpackはファイルをdist
フォルダーに保存せずに自動的にコンパイルします。 これは正常です。 ただし、同時にclean-webpack-plugin
が存在するため、 dist
フォルダーは消去されclean-webpack-plugin
。 その結果、ローカルサーバーの動作モードでは、 dist
フォルダーが空になり、これがgitの作業に悪影響を及ぼします(私のようにgitリポジトリにプロジェクトアセンブリを保存する場合のみ)。各サーバーの起動後、削除されたファイルにより多くの変更が表示されます。 たとえば、 npm run build-and-beautify
(以下のこのコマンドについて)のように、 npm run build-and-beautify
中にのみdist
フォルダーがクリーンアップされると便利です。 clean-webpack-plugin
必要な方法で構成できませんでした。 したがって、別のdel-cli
を使用しdel-cli
。これは、webpackに接続されておらず、個別に動作します。
npm install del-cli --save-dev
package.json
ファイルに変更を加えます。
{ ... "scripts": { ... "clear": "del-cli dist" }, ... }
CSSファイルアセンブリ
src/scss
を予約したSCSSファイルからCSSファイルを収集しsrc/scss
。 その中に、たとえば次の内容のstyle.scss
ファイルを作成します。
$font-stack: -apple-system, BlinkMacSystemFont,Roboto,'Open Sans','Helvetica Neue',sans-serif; @import "~bootstrap/scss/bootstrap"; @font-face { font-family: 'Roboto'; font-style: normal; font-weight: 400; src: url(../fonts/Roboto-Regular.ttf); } body { font-family: $font-stack; #logo { width: 10rem; } .container { img { width: 20rem; } } }
Bootstrapスタイルは、CSSファイルではなくSSS( @import "node_modules/bootstrap/scss/bootstrap"
@import "~bootstrap/scss/bootstrap";
)、必要に応じて、ライブラリの特定のプロパティを書き換えたり、ミックスインを使用したりすることができます。 jsファイルのアセンブリ中にjsファイルをBootstrapライブラリに接続するときにWebpackが必要なファイルの場所を認識している場合、スタイルを接続するときにnode_modules
フォルダーへのパスを指定する必要があります。
cssファイルを処理するには、 node-sass
、 sass-loader
、 css-loader
、およびextract-text-webpack-plugin
モジュールが必要です( extract-text-webpack-plugin
の次のバージョンでは、最後のプラグインはそれを必要としなくなります)。
重要! 執筆時点では、安定バージョンのextract-text-webpack-plugin
はWebpack 4で動作しません。したがって、 @next
を介してベータバージョンをインストールする必要があります。
npm install node-sass sass-loader css-loader extract-text-webpack-plugin@next --save-dev
すべてのプラグインを通常の方法ですぐにインストールできるようになることを願っています。
npm install node-sass sass-loader css-loader extract-text-webpack-plugin --save-dev
webpack.config.js
、次の変更を追加します。
... const ExtractTextPlugin = require("extract-text-webpack-plugin"); ... module.exports = { entry: [ ... './src/scss/style.scss' ], ... module: { rules: [{ ... { test: /\.(sass|scss)$/, include: path.resolve(__dirname, 'src/scss'), use: ExtractTextPlugin.extract({ use: [{ loader: "css-loader", options: { sourceMap: true, minimize: true, url: false } }, { loader: "sass-loader", options: { sourceMap: true } } ] }) }, ] }, plugins: [ new ExtractTextPlugin({ filename: './css/style.bundle.css', allChunks: true, }), ... ] };
エントリentry
ポイントに新しい入力ファイルstyle.scss
を追加しましたが、出力ファイルはoutput
では指定されず、 plugins
セクションのExtractTextPluginプラグインの呼び出しで指定されていることに注意してください。 sass-loader
およびcss-loader
パッケージのsourceMapソースマップのサポートが含まれています。
また、 style-loader
パッケージがないことにも気付くことができます。 style-loader
パッケージは、Webpackでcssを使用するときに最もよく言及されます。 このパッケージはcssコードをHTMLファイルに埋め込みます。これは単一ページのアプリケーションには便利ですが、複数ページのアプリケーションには便利ではありません。
そして、最も物議を醸す瞬間。 css-loader
パッケージの場合、 false
等しいurl
パラメーターを追加しました。 なんで? デフォルトでは、 url=true
であり、CSSを構築するときにWebpackが外部ファイルへのリンクを見つけた場合:背景画像、フォント(たとえば、この場合、 url(../fonts/Roboto-Regular.ttf)
フォントファイルurl(../fonts/Roboto-Regular.ttf)
へのリンクがあります)、それ彼はこれらのファイルを何らかの形で処理するように頼みます。 このため、最も一般的に使用されるパッケージは、 file-loader
(ビルドフォルダーにファイルをコピーする)またはurl-loader
(HTMLコードに埋め込みを試みる小さなファイル)です。 この場合、アセンブルされたcss内のファイルへの所定の相対パスを変更できます。
しかし、実際にはどんな問題に遭遇しましたか? SCSSコードをsrc/scss
があります。 SCSSコードで参照される画像を含むsrc/img
フォルダーがあります。 すべてが順調です。 しかし、たとえば、サードパーティのライブラリをサイトに接続する必要がありました(たとえば、lightgallery)。 彼女のSCSSコードはnode_modules/lightgallery/src/sass
にありnode_modules/lightgallery/src/sass
。このフォルダーは、相対パスを介してnode_modules/lightgallery/src/img
フォルダーの写真を参照します。 また、 style.scss
ライブラリスタイルを追加すると、 file-loader
はどこにあるかではなく、 src/img
フォルダー内でlightgallery
ライブラリの写真を探します。 そして、私はそれを克服できませんでした。
更新する Odrinが示唆するように、 resolve-url-loaderパッケージとfile-loaderを使用して、最後の問題に対処できます。
... module.exports = { ... module: { rules: [ ... { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: {name: 'img/[name].[ext]'} } ] }, { test: /\.(sass|scss)$/, include: path.resolve(__dirname, 'src/scss'), use: ExtractTextPlugin.extract({ use: [{ loader: "css-loader", options: { sourceMap: true, minimize: true//, //url: false } }, { loader: "resolve-url-loader" }, { loader: "sass-loader", options: { sourceMap: true } } ] }) } ... ] }, ... };
つまり、相対パスの代わりにresolve-url-loaderパッケージがwebpackが理解するパスを設定します。 そして、すでにファイルローダーは必要なファイルをコピーします。 問題は、ファイルローダーの名前プロパティにあります。 name: '[path]/[name].[ext]'
として指定する場合name: '[path]/[name].[ext]'
、私の例では、 dist\node_modules\lightgallery\src\img
フォルダーは、画像が既に配置されているdistフォルダーに表示されます。 いいえ、cssにはこのフォルダーへの正しいパスが登録されますが、きれいではありません。 したがって、パスなしでファイル名を指定することをお勧めします(たとえば、 name: 'img/[name].[ext]'
)。 確かに、すべての写真は1つのフォルダーに移動します-常に役立つとは限りません。
したがって、 url=false
に設定すると、SCSSコード内のファイルへのすべてのリンクに触れず、パスを変更せず、ファイルをコピーまたは埋め込みもしないと言います。後で個別に処理します。 おそらく、この解決策は不適切であり、より適切なアプローチを提案します。
HTMLページアセンブリ
楽しい部分に移りましょう。HTMLページを組み立てるのは、私にとって最大の困難でした。
HTMLページを作成するには、さまざまなタイプのテンプレートエンジンをサポートするhtml-webpack-plugin
を使用します。 また、 raw-loader
パッケージも必要になります。
npm install html-webpack-plugin raw-loader --save-dev
HTMLテンプレートエンジンとして、デフォルトのテンプレートエンジンlodashを使用します。 これは、アセンブリ前の典型的なHTMLページの外観です。
<% var data = { title: " | ", author: "Harrix" }; %> <%= _.template(require('./../includes/header.html'))(data) %> <p>text</p> <%= _.template(require('./../includes/footer.html'))(data) %>
最初に、 data
変数に、このページで使用するすべてのページ変数を登録します。 次に、 _.template(require())
。 _.template(require())
を_.template(require())
てヘッダーとフッターのテンプレートを埋め込みます。
重要な説明。 html-webpack-plugin
を介したHTMLページのアセンブルに関する記事では、通常、埋め込みテンプレートは次のコマンドで簡単に接続できます。
require('html-loader!./../includes/header.html')
ただし、同時に、これらの埋め込みテンプレートではlodash構文は機能しません(これがなぜ起こるのかまだわかりません)。 また、データ変数からのdata
はそこに転送されません。 そのため、webpackに、lodashテンプレートとして処理する必要があるテンプレートを埋め込むことを強制します。
これで、インラインテンプレートで本格的なlodash構文を使用できます。 以下のheader.html
ファイルheader.html
では、 <%=title%>
て記事のタイトル<%=title%>
印刷します。
<!doctype html> <html lang="ru"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="shortcut icon" href="favicon/favicon.ico"> <link rel="stylesheet" href="css/style.bundle.css"> <title><%=title%></title> </head> <body> <header><img src="img/logo.svg" id="logo"></header>
html-webpack-pluginパッケージには、複数のHTMLページを生成する機能があります。
plugins: [ new HtmlWebpackPlugin(), // Generates default index.html new HtmlWebpackPlugin({ // Also generate a test.html filename: 'test.html', template: 'src/assets/test.html' }) ]
しかし、プラグインの独自のインスタンスを作成する各ページを処方することは間違いなく良くありません。 そのため、 src/html/views
フォルダー内のすべてのHTMLファイルを検索してこのプロセスを自動化し、それらのnew HtmlWebpackPlugin()
独自のバージョンを作成します。
これを行うには、 webpack.config.js
ファイルに次の変更をwebpack.config.js
ます。
... const HtmlWebpackPlugin = require('html-webpack-plugin'); const fs = require('fs') function generateHtmlPlugins(templateDir) { const templateFiles = fs.readdirSync(path.resolve(__dirname, templateDir)); return templateFiles.map(item => { const parts = item.split('.'); const name = parts[0]; const extension = parts[1]; return new HtmlWebpackPlugin({ filename: `${name}.html`, template: path.resolve(__dirname, `${templateDir}/${name}.${extension}`), inject: false, }) }) } const htmlPlugins = generateHtmlPlugins('./src/html/views') module.exports = { module: { ... { test: /\.html$/, include: path.resolve(__dirname, 'src/html/includes'), use: ['raw-loader'] }, ] }, plugins: [ ... ].concat(htmlPlugins) };
generateHtmlPlugins
関数は、すべてのHTMLページを検索します。 関数コードには、 inject: false
設定があります。これは、WebpackにjsおよびcssファイルリンクをHTMLコードに埋め込む必要がないことを伝えます。header.htmlおよびfooter.html
ですべてを手動で行います。
埋め込まれたテンプレートは、最もよく提案されるhtml-loader
ではなく、 raw-loader
プラグイン(ファイルの内容は単にテキストとしてロードされる)によって処理されることにも注意してください。 また、CSSの場合と同様に、 file-loader
またはurl-loader
パッケージは使用しません。
そして、HTMLを扱う最後のオプションの瞬間が残っています。 JavaScriptファイルとCSSファイルは最小化されます。 しかし、私はHTMLファイルを作成し、逆に美しく、縮小しません。 したがって、すべてのHTMLファイルをアセンブルした後、何らかの美化プラグインでそれらを調べたいと思います。 そして、ここでセットアップを待っていました。Webpackでこれを行う方法が見つかりませんでした。 問題は、埋め込みテンプレートの挿入後にファイルを処理する必要があることです。
Webpackに関係なくこれを行うことができるhtml-cliパッケージを見つけました。 しかし、彼は月に38回のインストールを行っています。 つまり、これは2つのオプションを意味します。HTMLファイルを美しく見せるために誰も必要としないか、私が知らない別の一般的なソリューションがあります。 そして、この機能だけのために、Gulpはねじ込みを望んでいません。
このプラグインをインストールします。
npm install html-cli --save-dev
また、 package.json
ファイルには、Webpackで作業した後、2つのスペースで表形式のHTMLファイルを美しく表示するスクリプトをさらに2つ記述します。
"scripts": { "build-and-beautify": "del-cli dist && webpack --mode production && html dist/*.html --indent-size 2", "beautify": "html dist/*.html --indent-size 2" },
2018.04.11の更新 build-and-beautify
del-cli dist
にdel-cli dist
を追加したことに注意してください。これにより、 build-and-beautify
前にdist
フォルダーがクリアされます。
したがって、最終ビルドでは、* npm run buildコマンドではなく、 npm run build-and-beautifyコマンドを使用することをお勧めします。
残りのファイルをコピーする
js、cssファイル、HTMLページを生成しました。 画像ファイルやフォントなど、触れていないものや、 file-loader
やurl-loader
意識してコピーしていないものがあります。 したがって、残りのすべてのフォルダーをcopy-webpack-plugin
介してcopy-webpack-plugin
。
npm install copy-webpack-plugin --save-dev
webpack.config.js
ファイルwebpack.config.js
、変更を行います。
... const CopyWebpackPlugin= require('copy-webpack-plugin'); ... module.exports = { ... plugins: [ ... new CopyWebpackPlugin([{ from: './src/fonts', to: './fonts' }, { from: './src/favicon', to: './favicon' }, { from: './src/img', to: './img' }, { from: './src/uploads', to: './uploads' } ]), ]... };
それだけです これで、 npm run build-and-beautifyコマンドを使用してプロジェクトを収集し、組み立てられた静的サイトがdist
フォルダーに表示されます。
要約ファイル
{ "name": "static-site-webpack-habr", "version": "1.0.0", "description": "HTML template", "main": "src/index.js", "scripts": { "dev": "webpack --mode development", "build": "webpack --mode production", "build-and-beautify": "del-cli dist && webpack --mode production && html dist/*.html --indent-size 2", "watch": "webpack --mode development --watch", "start": "webpack-dev-server --mode development --open", "beautify": "html dist/*.html --indent-size 2", "clear": "del-cli dist" }, "dependencies": { "bootstrap": "^4.1.0", "jquery": "^3.3.1", "popper.js": "^1.14.3" }, "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.3", "babel-preset-env": "^1.6.1", "copy-webpack-plugin": "^4.5.0", "css-loader": "^0.28.11", "del-cli": "^1.1.0", "extract-text-webpack-plugin": "^4.0.0-beta.0", "html-cli": "^1.0.0", "html-webpack-plugin": "^3.2.0", "node-sass": "^4.8.3", "raw-loader": "^0.5.1", "sass-loader": "^6.0.6", "webpack": "^4.5.0", "webpack-cli": "^2.0.14", "webpack-dev-server": "^3.1.3" } }
const path = require('path'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const fs = require('fs') function generateHtmlPlugins(templateDir) { const templateFiles = fs.readdirSync(path.resolve(__dirname, templateDir)); return templateFiles.map(item => { const parts = item.split('.'); const name = parts[0]; const extension = parts[1]; return new HtmlWebpackPlugin({ filename: `${name}.html`, template: path.resolve(__dirname, `${templateDir}/${name}.${extension}`), inject: false, }) }) } const htmlPlugins = generateHtmlPlugins('./src/html/views'); module.exports = { entry: [ './src/js/index.js', './src/scss/style.scss' ], output: { filename: './js/bundle.js' }, devtool: "source-map", module: { rules: [{ test: /\.js$/, include: path.resolve(__dirname, 'src/js'), use: { loader: 'babel-loader', options: { presets: 'env' } } }, { test: /\.(sass|scss)$/, include: path.resolve(__dirname, 'src/scss'), use: ExtractTextPlugin.extract({ use: [{ loader: "css-loader", options: { sourceMap: true, minimize: true, url: false } }, { loader: "sass-loader", options: { sourceMap: true } } ] }) }, { test: /\.html$/, include: path.resolve(__dirname, 'src/html/includes'), use: ['raw-loader'] }, ] }, plugins: [ new ExtractTextPlugin({ filename: './css/style.bundle.css', allChunks: true, }), new CopyWebpackPlugin([{ from: './src/fonts', to: './fonts' }, { from: './src/favicon', to: './favicon' }, { from: './src/img', to: './img' }, { from: './src/uploads', to: './uploads' } ]), ].concat(htmlPlugins) };
<% var data = { title: " | ", author: "Harrix" }; %> <%= _.template(require('./../includes/header.html'))(data) %> <div class="container"> <p> .</p> <p><img src="uploads/test.jpg"></p> </div> <%= _.template(require('./../includes/footer.html'))(data) %>
<!doctype html> <html lang="ru"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="shortcut icon" href="favicon/favicon.ico"> <link rel="stylesheet" href="css/style.bundle.css"> <title><%=title%></title> </head> <body> <header><img src="img/logo.svg" id="logo"></header>
<footer><%=author%></footer> <script src="js/bundle.js"></script> </body> </html>
<!doctype html> <html lang="ru"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="shortcut icon" href="favicon/favicon.ico"> <link rel="stylesheet" href="css/style.bundle.css"> <title> | </title> </head> <body> <header><img src="img/logo.svg" id="logo"></header> <div class="container"> <p> .</p> <p><img src="uploads/test.jpg"></p> </div> <footer>Harrix</footer> <script src="js/bundle.js"></script> </body> </html>
ソースコード
レビューしたプロジェクトのあるリポジトリにリンクします。