web-dev-qa-db-ja.com

既存のPHPおよびJSプロジェクトでwebpackを使用する

フロントエンドフレームワークを使用せずに、jqueryとブートストラップを使用した既存のPHPプロジェクトがあります。

プロジェクトリソースの単一のエントリポイントを作成し、ノードjsパッケージマネージャーでjs依存関係を管理し、minify js cssとしてタスクを実行し、イメージのサイズ変更などのためにwebpackモジュールbundlerを使用しようとしています。また、単一のページを読み込むのに必要なブラウザの読み込み時間を改善します。

私はwebpackチュートリアルに出会い、それをインストールしてdev-serverをインストールしましたが、問題は、プロジェクトで現在のすべてのjsスクリプトとcssリンクを変換する方法を理解できないことです(私はたくさんあります)プロジェクトで複数の機能を提供するために使用されるjqueryおよびCSSライブラリの)webpackを使用します。

すべてのJSおよびCSSファイルをwebpackに適した方法で書き換える必要がありますか?移行を成功させるにはどうすればよいですか?

さらに、現在のphpアプリケーションをwebpack dev-serverで実行することはできません。そもそもそこで実行することを意図していますか?それまではプロジェクトのディレクトリのみをリストしています。

テストindex.jsファイルを作成し、次のwebpack構成を使用しました。

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

module.exports =
{
    entry: [
        './public/js/index.js',
        'webpack/hot/dev-server',
        'webpack-dev-server/client?http://localhost:8080'
    ],
    plugins: [
      new webpack.HotModuleReplacementPlugin()
    ],
    output: {
        path: path.join(__dirname, "public/dist/js"),
        publicPath : "http://localhost:8080/my_proj/public/dist/js",
        filename: "bundle.js"
    }

};

アプリケーションがwebpack dev-serverで実行されることを期待して、次のようにテストのためにスクリプトロードにbundle.jsを追加しました。

<script type="text/javascript" src="public/dist/js/bundle.js"></script>
<script type="text/javascript" src="public/js/jquery.min.js"></script>
<script type="text/javascript" src="public/js/jquery.migrate.js"></script>
<script type="text/javascript" src="public/js/jquery.bxslider.min.js"></script>
<script type="text/javascript" src="public/js/jquery.appear.js"></script>
<script type="text/javascript" src="public/js/jquery.countTo.js"></script>
<script type="text/javascript" src="public/js/bootstrap.js"></script>

ここで概念を理解し、この移行を成功させるにはどうすればよいですか?

47
KAD

まず、小さな質問に答えるには:

  • いいえ、webpack devサーバーを介してPHPアプリケーションを実行することは想定されていません。以下のLive Reloadingセクションで説明されています。
  • いいえ、資産を書き換える必要はありません。恐らく。以下のCSSおよびEdge Casesセクションを参照してください。

免責事項:あなたの質問のほんの一部を引き受けます。その範囲は、StackOverflowの1つの答えにまとめるには広すぎます。

連絡するだけです

  • webpackの開発および本番環境のセットアップ
  • 最初のJavaScriptをバンドルする

これにより、基礎を築くことができます。

また、リソースを読み通して追加およびリンクすることもできます。

じゃあ行こう。

必要条件

Node.jsとnpmがマシンにインストールされており、それらの使用方法のおおよその知識があると思います。

また、webpackwebpack-cliがプロジェクトの(dev)依存関係として(グローバルだけでなく)インストールされていると仮定します。

npm install --save-dev webpack webpack-cli

更新:この回答の以前のバージョンでは、webpack-cliをインストールする必要はありませんでした。バージョン4(2018年2月)の時点で、webpackのCLIは独自のパッケージに存在するため、追加の必須パッケージです。

開発と生産のワークフローを設定する

通常、本番環境とは異なる方法で開発を行います(本番環境での縮小、開発環境でのライブリロードなど)。

それを実現するために、構成ファイルを分割します。

ディレクトリ構造を準備する

あなたの質問からwebpack設定を無視することに同意しましょう。最初からやり直しますが、とにかくほとんどすべてを変更する必要があります。

まず、プロジェクトルート内にbuildフォルダーを作成します。プロジェクトのルートフォルダを設定ファイルで汚染したくないので、ビルド関連のものがそこに行きます。 (このフォルダーに別の名前を付けてもかまいませんが、このチュートリアルでは追跡します。)

そのフォルダー内にconfig.base.jsconfig.production.jsconfig.development.jsファイルを作成します。

すばらしい、2つのビルドチェーンの構成ファイルがあります。ただし、構成はまだ空なので、基本的なロジックを設定してみましょう。

webpack-mergeをインストールします

しかし、最初に、webpack-mergeをインストールする必要があります。

npm install --save-dev webpack-merge

このパッケージにより、複数のwebpack構成を深くマージできます。現在の環境に応じて、Webpack構成を作成するために使用します。

構成を調整する

ここでbuild/config.base.jsを調整します。

module.exports = {
  // We'll place webpack configuration for all environments here
}

このファイルは明らかに空のオブジェクトをすぐにエクスポートするだけですが、次の手順で必要になります。

このコードをbuild/config.production.jsに追加します。

const merge = require('webpack-merge')

module.exports = merge(require('./config.base.js'), {
  mode: 'production'

  // We'll place webpack configuration for production environment here
})

そして、ほぼ同じコードがbuild/config.development.jsに入ります:

const merge = require('webpack-merge')

module.exports = merge(require('./config.base.js'), {
  mode: 'development',
  watch: true

  // All webpack configuration for development environment will go here
})

私はこれが何をするかは非常に直感的だと思います:

config.development.js構成でwebpackを使用すると、共通の構成が取得され、独自の構成宣言がマージされます。

更新:上記の設定ファイルのmodeオプションは、webpack 4(2018年2月リリース)で追加されました。開発バンドルと本番バンドルに対して 一連の適切なデフォルト を設定します。

これで、コマンドラインからプロセスを実行すると次のようになります。

npx webpack --config build/config.development.js

# If the above doesn't work, you probably have an older version of npm (< 5.1) installed
# While npx is a really great tool, you can of course still call the path of the webpack executable manually:

node_modules/.bin/webpack --config build/config.development.js

...およびproduction環境の場合はその逆です。

このコマンドはかなり使いにくいですが、心配する必要はありません。後で説明します。

ヘルパーファイルを作成する

簡単に交換できるように一元化する情報があります。ファイルパスはそのようなものです。それでそれらを抽出しましょう。

buildフォルダーにpaths.jsを作成し、後で使用するいくつかのパスをエクスポートします。

const path = require('path')

// I'm really just guessing your project's folder structure from reading your question,
// you might want to adjust this whole section
module.exports = {
  // The base path of your source files, especially of your index.js
  SRC: path.resolve(__dirname, '..', 'public'),

  // The path to put the generated bundle(s)
  DIST: path.resolve(__dirname, '..', 'public', 'dist'),

  /*
  This is your public path.
  If you're running your app at http://example.com and I got your DIST folder right,
  it'll simply be "/dist".
  But if you're running it locally at http://localhost/my/app, it will be "/my/app/dist".

  That means you should probably *not* hardcode that path here but write it to a
  machine-related config file. (If you don't already have something like that,
  google for "dotenv" or something similar.)
  */
  ASSETS: '/dist'
}

エイリアスを作成する

上記のように、次のようにdevelopmentモードでビルドチェーンを技術的に実行できます。

npx webpack --config build/config.development.js

ただし、これは不快なほど冗長なコマンドなので、変更しましょう。

npmスクリプトを使用してビルドプロセスを実行する方がはるかに便利です。次のように、環境ごとに1つのスクリプトをpackage.jsonに追加します。

{
  "scripts": {
    "dev": "webpack --config build/config.development.js",
    "prod": "webpack --config build/config.production.js"
  }
}

これで、npm run dev respを使用してビルドチェーンを実行できます。 npm run prod –覚えやすく、入力も高速です。

...もちろん、構築するものがあればすぐに。

JavaScriptをバンドル

さて、これは実際のところ、あまり多くのことを達成することなく、かなりの量の作業でした。

それでは、もっとエキサイティングなことから始めましょう。JavaScriptエントリポイントを定義します。

エントリポイントを定義する

次のコードをbuild/config.base.jsに追加します(既存のコードを完全に置き換えます):

const path = require('path')
const { SRC, DIST, ASSETS } = require('./paths')

module.exports = {
  entry: {
    scripts: path.resolve(SRC, 'js', 'index.js')
  },
  output: {
    // Put all the bundled stuff in your dist folder
    path: DIST,

    // Our single entry point from above will be named "scripts.js"
    filename: '[name].js',

    // The output path as seen from the domain we're visiting in the browser
    publicPath: ASSETS
  }
}

JavaScriptファイルを作成する

上記の構成では、index.jsフォルダー(SRC/jsで定義)にbuild/paths.jsが存在することを想定しています。

次の内容でそのファイルを作成しましょう:

import './jquery.min.js'
import './jquery.migrate.js'
import './jquery.bxslider.min.js'
import './jquery.appear.js'
import './jquery.countTo.js'
import './bootstrap.js'

ご覧のとおり、index.jsは、使用するすべてのファイルをインポートするだけです。

今走ったら

npm run prod

端末からDISTフォルダーにscripts.jsファイルが作成されます。プレーンol '<script>タグを使用して、マークアップにそれを含めることができます。

おめでとうございます、Webpackのセットアップは正常に完了しました!

深く潜る

このミニチュートリアルは、webpackでできることの表面を実際に削っただけです。これにより、構成の非常に強固な基盤が得られ、必要なものを何でも入力できます。そして、それは実際には非常に多くのものになります。

あなたが強化したいと思うかもしれないいくつかのリンクを読み通すためにいくつかリストします。

webpackの概念

Webpackを使用したい場合、その基礎となる概念がわからなければ、それを行うのは困難です。 JuhoVepsäläinen webpackの使用開始に関する素晴らしいガイドを作成してくれました。彼はWebpackのコアコントリビューターでもあるため、彼が何を話しているのかを確実に把握できます。

特にloadersは、あなたが本当に知る必要がある概念です。

このリストのヒントの多くもここで説明されています。

続きを読む: SurviveJS – webpack tutorial

コード分​​割

名前のとおり:すべてのJavaScriptを1つの大きな出力ファイルにまとめたくない場合があります。

アプリケーションの特定のページでのみ必要なバンドルの部分を分割するのは、webpackが行う仕事です。

また、プロジェクトのJavaScriptを使用する頻度に応じて、キャッシュの目的でバンドルからサードパーティコードを分離することをお勧めします。

詳細: webpackドキュメンテーション–コード分割

キャッシング

コンテンツに依存するバンドルされたファイル名にハッシュを追加することにより、サイトのキャッシュ動作を強化したい場合があります。これにより、(たとえば)script.31aa1d3cad014475a618.jsではなくscripts.jsが作成されます。

そのファイルは、コンテンツが変更されるとすぐにファイル名も変更されるため、無期限にキャッシュできます。

その後、PHPコードはwebpack-manifest-pluginを使用して、生成されたファイル名にアクセスします。

続きを読む:

トランスパイリング

サイトのJavaScriptで最新のES2015コードを使用する場合(および非常緑のブラウザーをターゲットにしている場合)、それらを通常のES5に変換します。 (「ES2015」という用語が意味をなさない場合、おそらく使用していないため、この段落を無視できます。)

詳細: babel-loader –スクリプトでBabelを実行するローダー

CSS

CSS用のwebpackローダーがあります。そしてサス。そして、PostCSS。あなたに必要なものは何でも。

また、おそらく<script>タグを使用してCSSを含める予定はないので、実際の.cssファイルを生成するためのExtract Text Pluginを理解してください。

更新:Extract Text Pluginは非常に確立されています。ただし、実際には一種のハックです。webpackがターゲット言語としてJavaScriptしか認識していない場合でも、.cssファイルを生成します。

ただし、webpack 4の時点ではこれは当てはまりません。現在、CSSを含む任意のモジュールタイプを定義するシステムがあります。

長い話: webpackのネイティブCSSサポートを期待してExtract Text Pluginしばらくすると

ここでwebpackがどのように機能するかを理解するまで、これは私にとって本当の痛みポイントだったので、これについて言及します。

Webpackはurl(...)ステートメントを認識し、ソースファイルに関連して解決しようとすることに注意してください

つまり、ソースファイルpublic/css/main.css

body {
  background: url('../img/bg.jpg');
}

出力パスがpublic/dist/css/bundle.cssの場合、次のように変換されます。

body {
  background: url('../../img/bg.jpg');
}

続きを読む:

縮小する

更新:webpack 4は2018年2月にリリースされたため、このセクションは古いものです。新しいmodeオプションを"production"に設定すると、JavaScriptの縮小が自動的に適用されるようになりました。

JavaScriptを縮小するwebpack用の Terser プラグインがあります。 CSSの縮小は、前述のcss-loaderプラグインに既に組み込まれている機能です。

続きを読む: Terser webpack Plugin

画像の最適化

webpackはタスクランナーではなくバンドラーです。したがって、画像の最適化は、真のWebpackタスクではありません。おそらく、実際のタスクランナーを使用するか、このためにいくつかのnpmスクリプトを定義する方が良いでしょう。

これは、webpackがこれを実行できないことを意味するものではありません。ほとんどすべてのプラグインがあります。

続きを読む:

  • imagemin 単独で画像をかなりきれいに縮小できます。
  • imagemin-webpack-plugin は、そのプロセスをWebpackビルドチェーンに統合します。

ライブリロード

ライブリロードの問題の原因は非常に単純です。webpackdevサーバーは、静的ファイルのみを提供する単純なNode.jsサーバーです。

あなたの場合、おそらくwebpack-dev-serverはまったく間違ったツールです。 webpack-livereload-pluginタグを介してインクルードできるライブリローダーの代わりに、<script>を試してください。

続きを読む: webpack-livereload-plugin

ソースマップ

更新:webpack 4(2018年2月にリリース)の時点で、新しいmodeオプションが"development"に設定されると、ソースマップが自動的に生成されます。

必ずソースマップを使用してください。彼らはあなたが泣きたいと思うほど簡単にバンドルであなたの仕事をするでしょう。

詳細: webpackドキュメンテーション–ソースマップ

エッジケース

通常、webpackで処理する既存のスクリプトはすべて正常に実行されるはずです。

私の頭に浮かぶ唯一の例外は、グローバルエンティティに関するものです。

次のコードを見てください:

function myFunc () {
  console.log('I exist!')
}

プレーンなJavaScriptファイル内のこのコードは、JSコードのあらゆる場所でmyFuncを利用可能にします。ただし、webpackバンドルコードはコールバック関数内にラップされるため(したがってグローバルスコープを離れる)、その関数へのアクセスはもうありません。

サードパーティのライブラリは問題になりません。通常、グローバルをwindowオブジェクトに直接割り当てますが、プロジェクトで既にJSコードを記述している場合は、注意する必要があります。

自動化!

できるだけ多くのワークフローを自動化する必要があります。

プッシュする前/プルした後、gitフックを介してnpm run prodを実行することを検討してください。


お役に立てれば。

132
Loilo

既存のvueテンプレートと@Loiloの回答に基づいて、vueテンプレートを作成しました。vue-cliでインストールできます。このテンプレートを使用すると、既存の環境で拡張または統合できるvueアプリケーションにすぐにアクセスできます。

npm install -g vue-cli
vue init delcon/webpack-simple my-project
cd my-project
npm install

devwatch:

このテンプレートには、webpack-dev-serverを使用する代わりにファイル変更を監視する追加のdevwatch実行オプションがあります。これにより、既存のWebサーバー環境で使用できるようになります。

npm run devwatch

dev:

デフォルトのwebpack-dev-serverで実行するには、<script src="http://localhost:35729/livereload.js"></script>index.htmlを削除します。

npm run dev

ビルド:

本番用にプロジェクトをビルドするには:

npm run build
0
Delcon