[javascript] 웹팩에서 jQuery 플러그인 종속성 관리

내 응용 프로그램에서 Webpack을 사용하고 있는데 모든 JavaScript 파일 / 코드에 대해 bundle.js와 jQuery 및 React와 같은 모든 라이브러리에 대해 vendor.js라는 두 개의 진입 점을 만듭니다. jQuery를 종속 플러그인으로 사용하고 vendor.js에도 플러그인을 사용하려면 어떻게해야합니까? 해당 플러그인에 여러 종속성이있는 경우 어떻게합니까?

현재이 jQuery 플러그인을 사용하려고합니다-https: //github.com/mbklein/jquery-elastic . Webpack 문서에는 providePlugin 및 imports-loader가 언급 되어 있습니다. providePlugin을 사용했지만 여전히 jQuery 객체를 사용할 수 없습니다. 내 webpack.config.js의 모습은 다음과 같습니다.

var webpack = require('webpack');
var bower_dir = __dirname + '/bower_components';
var node_dir = __dirname + '/node_modules';
var lib_dir = __dirname + '/public/js/libs';

var config = {
    addVendor: function (name, path) {
        this.resolve.alias[name] = path;
        this.module.noParse.push(new RegExp(path));
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jquery: "jQuery",
            "window.jQuery": "jquery"
        }),
        new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity)
    ],
    entry: {
        app: ['./public/js/main.js'],
        vendors: ['react','jquery']
    },
    resolve: {
        alias: {
            'jquery': node_dir + '/jquery/dist/jquery.js',
            'jquery.elastic': lib_dir + '/jquery.elastic.source.js'
        }
    },
    output: {
        path: './public/js',
        filename: 'bundle.js'
    },
    module: {
        loaders: [
            { test: /\.js$/, loader: 'jsx-loader' },
            { test: /\.jquery.elastic.js$/, loader: 'imports-loader' }
        ]
    }
};
config.addVendor('react', bower_dir + '/react/react.min.js');
config.addVendor('jquery', node_dir + '/jquery/dist/jquery.js');
config.addVendor('jquery.elastic', lib_dir +'/jquery.elastic.source.js');

module.exports = config;

그러나 그럼에도 불구하고 브라우저 콘솔에서 여전히 오류가 발생합니다.

잡히지 않은 ReferenceError : jQuery가 정의되지 않았습니다

마찬가지로 imports-loader를 사용하면 오류가 발생합니다.

요구가 정의되지 않았습니다 ‘

이 줄에 :

var jQuery = require("jquery")

그러나 vendor.js 파일에 플러그인을 추가하지 않고 다른 JavaScript 코드 파일을 포함하는 방법과 같이 일반적인 AMD 방식으로 필요할 때 동일한 플러그인을 사용할 수 있습니다.

define(
[
    'jquery',
    'react',
    '../../common-functions',
    '../../libs/jquery.elastic.source'
],function($,React,commonFunctions){
    $("#myInput").elastic() //It works

});

그러나 jquery.elastic.source.js가 bundle.js의 JavaScript 코드와 함께 번들로 제공되고 모든 jQuery 플러그인이 vendor.js 번들에 포함되기를 원하기 때문에 이것은 내가하고 싶은 것이 아닙니다. 어떻게 이것을 달성 할 수 있습니까?



답변

레거시 공급 업체 모듈을 포함시키는 방법에 대해 서로 다른 접근 방식을 혼합했습니다. 이것이 내가 다루는 방법입니다.

1. 축소되지 않은 CommonJS / AMD보다 선호 dist

대부분의 모듈 dist은 해당 main필드에 버전을 연결합니다 package.json. 이것은 대부분의 개발자에게 유용하지만, 웹팩의 경우 src웹팩이 종속성을 더 잘 최적화 할 수 있기 때문에 (예 :을 사용하는 경우 DedupePlugin) 웹 앨범 버전의 별명을 지정하는 것이 좋습니다 .

// webpack.config.js

module.exports = {
    ...
    resolve: {
        alias: {
            jquery: "jquery/src/jquery"
        }
    }
};

그러나 대부분의 경우 dist버전도 잘 작동합니다.


2.를 사용하여 ProvidePlugin암시 적 전역을 주입합니다

대부분의 기존 모듈의 jQuery 플러그인에서처럼, 특정 전역의 존재에 의존 $하거나 jQuery. 이 시나리오에서는 var $ = require("jquery")전역 $식별자 가 발생할 때마다 앞에 추가되도록 웹팩을 구성 할 수 있습니다 .

var webpack = require("webpack");

    ...

    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        })
    ]

3. imports-loader 를 사용하여 구성this

일부 기존 모듈에 의존 this되는 window객체입니다. 이는 모듈이 CommonJS 컨텍스트에서 this같을 때 문제가됩니다 module.exports. 이 경우 대체 할 수 있습니다 this으로 수입 로더 .

실행 npm i imports-loader --save-dev

module: {
    loaders: [
        {
            test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
            loader: "imports-loader?this=>window"
        }
    ]
}

수입 로더는 또한 모든 종류의 변수를 수동으로 주입하는 데 사용될 수 있습니다. 그러나 대부분 ProvidePlugin암시 적 글로벌에 대해서는 더 유용합니다.


4. imports-loader 를 사용하여 AMD를 비활성화하십시오

AMD, CommonJS 및 레거시와 같은 다양한 모듈 스타일을 지원하는 모듈이 있습니다. 그러나 대부분의 경우 처음으로 확인한 define다음 기발한 코드를 사용하여 속성을 내 보냅니다. 이 경우을 설정하여 CommonJS 경로를 강제 실행하는 데 도움이 될 수 define = false있습니다.

module: {
    loaders: [
        {
            test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
            loader: "imports-loader?define=>false"
        }
    ]
}

5. 스크립트 로더 를 사용하여 스크립트 를 전체적으로 가져옵니다.

전역 변수에 신경 쓰지 않고 레거시 스크립트가 작동하기를 원한다면 스크립트 로더를 사용할 수도 있습니다. 마치 <script>태그 를 통해 포함 된 것처럼 전역 컨텍스트에서 모듈을 실행합니다 .


6. noParse큰 dist를 포함하는 데 사용

AMD / CommonJS 버전의 모듈이없고를 포함하려는 dist경우이 모듈을로 표시 할 수 있습니다 noParse. 그런 다음 webpack은 구문 분석하지 않고 모듈을 포함하므로 빌드 시간을 향상시키는 데 사용할 수 있습니다. 이는 ,와 같이 AST가 필요한 기능이 ProvidePlugin작동하지 않음을 의미합니다.

module: {
    noParse: [
        /[\/\\]node_modules[\/\\]angular[\/\\]angular\.js$/
    ]
}


답변

jquery에 대한 전역 액세스의 경우 몇 가지 옵션이 있습니다. 가장 최근의 웹팩 프로젝트에서 jquery에 대한 전역 액세스를 원했기 때문에 플러그인 선언에 다음을 추가했습니다.

 plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    })
  ]

이는 전역 참조 $ 및 jQuery를 통해 JavaScript 소스 코드 내에서 jquery에 액세스 할 수 있음을 의미합니다.

물론, npm을 통해 jquery를 설치해야합니다.

$ npm i jquery --save

이 접근법의 실제 예제를 보려면 github에서 내 앱을 포크하십시오.


답변

나는 당신이하려는 일을 잘 이해하고 있는지 모르겠지만 jQuery가 전역 컨텍스트 (창)에 있어야하는 jQuery 플러그인을 사용해야했고 다음을 내 안에 넣었습니다 entry.js.

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

의 I는 내가 원하는 위치 요구해야 jqueryplugin.min.js하고 window.$예상대로 플러그인 확장됩니다.


답변

나는 일을 노출하면서 잘 작동 가지고 $jQuery웹팩 3.8.1 및 다음 글로벌 변수로.

jQuery를 프로젝트 종속성으로 설치하십시오. @3.2.1최신 버전 설치 를 생략 하거나 다른 버전을 지정할 수 있습니다 .

npm install --save jquery@3.2.1

설치 expose-loader설치되어 있지 않은 경우 개발 의존한다.

npm install expose-loader --save-dev

jQuery를로드하고 노출하도록 Webpack을 구성하십시오.

// webpack.config.js
const webpack = require('webpack')

module.exports = {
  entry: [
    // entry bits
  ],
  output: {
    // output bits
  },
  module: {
    rules: [
      // any other rules
      {
        // Exposes jQuery for use outside Webpack build
        test: require.resolve('jquery'),
        use: [{
          loader: 'expose-loader',
          options: 'jQuery'
        },{
          loader: 'expose-loader',
          options: '$'
        }]
      }
    ]
  },
  plugins: [
    // Provides jQuery for other JS bundled with Webpack
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    })
  ]
}


답변

이것을 webpack.config.js의 플러그인 배열에 추가하십시오

new webpack.ProvidePlugin({
    'window.jQuery': 'jquery',
    'window.$': 'jquery',
})

그런 다음 jquery가 정상적으로 필요합니다.

require('jquery');

고통이 계속해서 다른 스크립트가 그것을 볼 수 있다면 (JS 항목을 통해) 전역 컨텍스트에 명시 적으로 배치하십시오.

window.$ = jQuery;


답변

webpack.config.js 파일에서 아래를 추가하십시오.

 var webpack = require("webpack");
 plugins: [
    new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery"
    })
 ],

npm을 사용하여 jQuery를 설치하십시오.

$ npm i jquery --save

app.js 파일에서 아래 줄을 추가하십시오.

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

이것은 나를 위해 일했습니다. 🙂


답변

제공된 답변 중 일부를 시도했지만 그중 아무것도 작동하지 않는 것 같습니다. 그런 다음 이것을 시도했습니다.

new webpack.ProvidePlugin({
    'window.jQuery'    : 'jquery',
    'window.$'         : 'jquery',
    'jQuery'           : 'jquery',
    '$'                : 'jquery'
});

사용중인 버전에 관계없이 작동하는 것 같습니다