質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.63%

Webpackでjqueryなどが認識されない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 3,338

nnahito

score 1841

 はじめに

Node系、npm系初心者です。

 疑問

yarnを使ったパッケージ管理で、
yarn install(yarn add?)したあとにnode_modulesフォルダに入ったJSファイルを
<script src="js/dist/main.min.js"></script>形式で使いたい。

とりあえずjqueryをやってみる。

 やったこと

まず、yarnでjqueryを入れる。

yarn add jquery

すると、node_modulesフォルダにjqueryフォルダができ、中にjquery.jsがあることが確認できる。
このまま使ってはいけないらしいので、webpackでコンパイル(?)を行う。


まずは必要プラグインを整える。

yarn add gulp gulp-uglify webpack-stream webpack gulp-concat

次に、app.jsの作成

import './node_modules/jquery/dist/jquery.js'

gulpfile.jsの作成

const gulp = require('gulp');
const uglify = require('gulp-uglify');
const webpackStream = require("webpack-stream");
const webpack = require("webpack");
const concat = require("gulp-concat");


// webpackの設定ファイルの読み込み
const webpackConfig = require("./webpack.config");

gulp.task('default', function () {
});

// task
gulp.task('jsmin', function () {
    // 設定ファイルで指定してあるデータをコンパイルして、吐き出す
    return webpackStream(webpackConfig, webpack)
        .pipe(gulp.dest("js/dist/"));
});

webpack.config.jsの作成

const path = require('path');

// Webpack化して出力する設定
module.exports = {
    // モード値を production に設定すると最適化された状態で、
    // development に設定するとソースマップ有効でJSファイルが出力される
    mode: "production",

    // コンパイル元
    entry: path.resolve(__dirname, "app.js"),
    // コンパイル先のファイル名
    output: {
        filename: "[name].min.js",
    },
}

ここまでのフォルダ構成

イメージ説明


gulpを実行

>gulp jsmin

[12:41:17] Using gulpfile ~\Desktop\node\gulpfile.js
[12:41:17] Starting 'jsmin'...
[12:41:17] Version: webpack 4.26.1
Built at: 2018-12-02 12:41:17
      Asset      Size  Chunks             Chunk Names
main.min.js  86.1 KiB       0  [emitted]  main
Entrypoint main = main.min.js
[12:41:17] Finished 'jsmin' after 808 ms

指定通り、js/dist/main.min.jsが作成されていることを確認。

イメージ説明


main.min.jsを呼び出してみる。
index.htmlを作成

<script src="js/dist/main.min.js"></script>

<script>
    $(document).ready(function () {
        alert('aaa');
    })
</script>

ブラウザで見てみる。
jqueryが拾えていない…?

イメージ説明


これは何故なのでしょうか?
どの指定が間違っているかが現在の知識では検討もつかず……

ご存知の方がいらっしゃいましたらご教示いただけますと幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • CHERRY

    2018/12/02 13:58

    「普通に使いたい。」とは、どのようにでしょうか? html ファイルから直接呼び出したいということでしょうか? 普通の定義は、人によって違うと思うので具体的に記載していただけないでしょうか?

    キャンセル

  • nnahito

    2018/12/02 14:40

    コードの通り、jqueryを「js/dist/main.min.js」に出力し、index.htmlで「js/dist/main.min.js」を呼び出し、そのindex.html内でjqueryを使いたいのです。コードはすべて提示しております。ご不明点がありましたらお手数ですが、コード内の箇所でのご指摘をいただけますとありがたいです。

    キャンセル

回答 2

checkベストアンサー

+2

import './node_modules/jquery/dist/jquery.js'

umdなのでimportしてもグローバルには展開されません。

import jquery from './node_modules/jquery/dist/jquery.js';
を毎回使う場所で行ってください。

node_modulesのパスは解決されるので
import jquery from 'jquery'; 
でも取れると思います。

$でみたければ、自身で代入すればよいです。
import jquery from 'jquery'; 
window.$ = jquery

 追記

es5というバージョンのjavascriptにはjsのモジュール化という仕組みがありません。
そのため、複数のjsファイルでのやり取りはグローバルオブジェクト(window)でやり取りを行います

hoge.js

window.hoge = funciton(){ 処理 }

piyo.hs

window.hoge();   //hoge.jsで定義した関数を使う

このやり方は、ファイル数が増えれば増えるほど、定義場所が不明になったり、piyo.jsより先にhoge.jsを読み込むなど読み込む順を気にする必要があったりと、色々問題があり、あまりよろしくありません。


nodeはこれを解決するためにcommonJsというjsファイルをモジュール化する仕組みを取り入れる事で解決しました。

hoge.js

module.exports.hoge = function(){ 処理 }

piyo.js

var result = require('./hoge');
result.hoge();  //hoge.jsで定義した関数を使う

このようにする事で、使用者がrequireで読み込むjsファイルを指定するので、定義場所は明確にわかりますし、
読み込みの順番を管理する必要がないなど先ほどの問題を解決しました

commonJsについてはご自身で調べてください。


browserでも、この仕組みを使いたい訳ですが、あくまでnodeで実装されている仕組みであり、browserでは使えません。

これをbrowserでも使えるようにするために開発されたものがwebpackです。


jqueryscriptタグで読み込まれたかrequire(import)で読み込まれたか検知する仕組みがはいており、
scriptタグで読み込まれた場合は、window.jquery(window.$)に展開し、
require(import)で読み込まれた場合はmodule.exportsでjqueryオブジェクトを返すだけになっています。

そのためimport 'jquery'でjqueryを読み込んでもwindow.$には何も入りません。


import jquery from 'jquery'
window.$ = jquery;

これを行うと問題は解決しますが、webpackでモジュール化をする利点が一切なくなります。
webpackを使うのであれば、個々のjsファイルで都度importするのが正しい使い方になります

hoge.js

import jquery from 'jquery'

jqueryオブジェクトを使う

piyo.js

import jquery from 'jquery'

jqueryオブジェクトを使う

app.js

import './hoge';
import './fuga';

最後にrequireとimportの違いですが、
browserにはモジュール化の仕組みがないと記載しましたが、新しいバージョンのjavascriptではモジュール化の仕組みが入りました。(chromeなどではもう使えますが、IEでは使えません)
これは、nodeのcommonJsと同じような仕組みなのですが、書き方が変わり、import/exportになっています

esModuleと呼ばれる仕組みなので。ご自身で調べてみてください。

webpackは、どちらの書き方にも対応しているので、どちらの書き方も解釈することができます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/02 23:43

    ご回答と丁寧な解説誠にありがとうございます。
    私自身、まだまだ理解が及んでいませんので、じっくりと拝見させていただきます。

    取り急ぎ読ませていただいた感じでは、
    (1)現在の私のやり方はモダンなやり方ではない
    (2)このやり方でvueなどを扱うには、完全にJSファイルを分ける必要がある(htmlファイル内での<script>では使えない)
    という認識で間違いないでしょうか?

    キャンセル

  • 2018/12/03 08:05

    ひとまず、そういう認識で良いと思います。

    html内のscriptタグはwebpackの管理外なので、こことやり取りをするためには昔ながらのグローバルオブジェクトでやりとりする必要が出てきます。
    そのため、webpackを使う意味がなくなってしまうので基本的には間違っています。
    jsファイルを分けて、すべてwebpackの管理下におくのが正しいやり方です。

    (実際はwebpackで色々設定できるので、ある程度理解した後にwebpackの設定を細かく確認されると良いと思います)

    キャンセル

  • 2018/12/03 09:05

    ご回答有り難うございます!
    長々とありがとうございました。
    勉強させていただきます

    キャンセル

-2

初心者ほど余計なことはしないほうがいい。混乱するだけ。
jQuery使いたいだけならwebpackなんかいらないので直接使えばいい。
npmさえも不要でCDNで十分。

・webpack使う場合
gulpはいらない。webpack.config.jsも自分で書かない。
Laravel mixを単体で使うのが一番簡単。
Laravelプロジェクトからpackage.json,webpack.mix.js,resourcesを持ってきて不要な部分を削除。
https://github.com/laravel/laravel
jQueryの読み込みはこうなってる。他にも使用方法はあるけど気にしなくていい。

window.$ = window.jQuery = require('jquery');


ファイルの出力先はwebpack.mix.jsで変えればいいので
npm run prodでビルドして終わり。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/02 13:50

    ご回答有り難うございます。

    まず、Laravelではありません。
    そしてWebpackの勉強ですので、

    初心者ほど余計なことはしないほうがいい。混乱するだけ。
    jQuery使いたいだけならwebpackなんかいらないので直接使えばいい。
    npmさえも不要でCDNで十分。

    と言われると、「勉強するな」と言われているような印象を抱きます……

    すいませんが、意図から外れすぎたご回答は避けていただけますと幸いです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる