2017-09-26 49 views
0

我正在從RequireJS項目遷移到Webpack。 後者對我來說是新的,我將其用作學習練習。 在RequireJS我可以這樣註冊的東西:Webpack 2:爲jQWidgets提供像RequireJS一樣的勻場?

shim: { 
    'jqxcore': { 
     exports: "$", 
     deps: ["jquery"] 
    }, 
    'jqxtree': { 
     exports: "$", 
     deps: ["jquery", "jqxcore"] 
    }, 
    'jqxbutton': { 
     exports: "$", 
     deps: ["jquery", "jqxcore"] 
    }, 
    'jqxsplitter': { 
     exports: "$", 
     deps: ["jquery", "jqxcore"] 
    }, 
    'jqxmenu': { 
     exports: "$", 
     deps: ["jquery", "jqxcore"] 
    } 
} 

,然後只需要「jqxsplitter」比如,像這樣:

import "jqxsplitter" 

之類的東西將被正確註冊和加載。 現在我正在看幾個指南/教程/我發現從RequireJS遷移到Webpack時發現的,例如this one和this之一。 所以以下這些見解,我想在我webpack.config.js是這樣的:

"use strict"; 

// Required to form a complete output path 
const path = require("path"); 

// Plagin for cleaning up the output folder (bundle) before creating a new one 
const CleanWebpackPlugin = require("clean-webpack-plugin"); 

const HtmlWebpackPlugin = require("html-webpack-plugin"); 
const webpack = require("webpack"); 

// Path to the output folder 
const bundleFolder = "./wwwroot/"; 

// Path to the app source code 
const appFolder = "./app/"; 

module.exports = { 
    // Application entry point 
    entry: { 
     main: appFolder + "index.ts", 
     vendor: [ 
      "knockout", 
      "jquery", 
      "jqxcore" 
     ], 
     jqxsplitter: "jqxsplitter" 
    }, 

    // Output file 
    output: { 
     filename: "[name].js", 
     chunkFilename: "[name].js", 
     path: path.resolve(bundleFolder) 
    }, 
    module: { 
     rules: [{ 
      test: /\.tsx?$/, 
      loader: "ts-loader", 
      exclude: /node_modules/ 
     }, { 
      test: /\.html?$/, 
      loader: "html-loader" //TODO: file-loader? 
     }], 
     loaders: [{ 
      test: /jqxcore/, 
      loader: "imports?jquery!exports?$" 
     }, { 
      test: /jqxsplitter/, 
      loader: "imports?jquery,jqxcore!exports?$" 
     }] 
    }, 
    resolve: { 
     extensions: [".tsx", ".ts", ".js"], 
     alias: { 
      "jqxcore": "jqwidgets-framework/jqwidgets/jqxcore", 
      "jqxsplitter": "jqwidgets-framework/jqwidgets/jqxsplitter" 
     } 
    }, 
    plugins: [ 
     new CleanWebpackPlugin([bundleFolder]), 
     new HtmlWebpackPlugin({ 
      filename: "index.html", 
      template: appFolder + "index.html", 
      chunks: ["main", "vendor"] 
     }), 
     new webpack.optimize.CommonsChunkPlugin({ 
      name: "vendor", 
      filename: "vendors.js", 
      minChunks: Infinity 
     }) 
    ], 
    devtool: "source-map" 
}; 

相關部分(我認爲)是

module: { 
    loaders: [{ 
     test: /jqxcore/, 
     loader: "imports?jquery!exports?$" 
    }, { 
     test: /jqxsplitter/, 
     loader: "imports?jquery,jqxcore!exports?$" 
    }] 
}, 

這是很清楚如何的「語法進口/出口「應該等於RequireJS的」deps「和」exports「。 不過我做這在我的index.ts文件(應用程序根)時:

import "jqwidgets-framework/jqwidgets/jqxsplitter"; 

我得到運行我的應用程序時,「jqxBaseFramework是未定義」的錯誤。 我在jQWidgets的論壇上發現了對這個錯誤的引用,但是沒有一個答案似乎真的解決了這個問題,或者包含了AOT編譯之類的東西,它不適用於我的情況,因爲我沒有使用Angular。

我已經posted同樣的問題在jQWidges論壇,但至今沒有實際的答案(現在要在兩週),只有一個通用的答案說jqxwhateverplugin.js之前,我應該加載jqxcore.js。 嗯,顯然,這就是我正在嘗試使用勻場完成的。

任何想法?

回答

0

那麼我結束了深潛,併爲自己找出了答案。 如果有人發現自己身處相同或相似的小船,這裏的解決方案就是如此。

如果您美化jQWidgets腳本文件jqxcore.js,您會看到它創建了一個通常爲名爲「jqxBaseFramework」的全局變量,該變量當然不會全局公開,只能在其自己的模塊中顯示。這就是問題所在。

的解決方案是使用這種配置:

module: { 
    rules: [{ 
     test: /jqxcore/, 
     use: "exports-loader?jqxBaseFramework" 
    }, { 
     test: /jqxknockout/, 
     use: ["imports-loader?jqxBaseFramework=jqxcore,ko=knockout", "exports-loader?jqxBaseFramework"] 
    }, { 
     test: /jqxsplitter/, 
     use: "imports-loader?jqxBaseFramework=jqxknockout" 
    }] 
}, 
resolve: { 
    ... 
    alias: { 
     "knockout": "knockout/build/output/knockout-latest", 
     "jqxcore": "jqwidgets-framework/jqwidgets/jqxcore", 
     "jqxknockout": "jqwidgets-framework/jqwidgets/jqxknockout", 
     "jqxsplitter": "jqwidgets-framework/jqwidgets/jqxsplitter" 
    } 
}, 

我想,一旦點擊,這一切纔有意義。 jqxcore模塊現在將導出其具有相同名稱的jqxBaseFramework變量。

我加入了淘汰賽的支持,而在它。 jqxknockout期望兩個全局變量正常工作:ko(敲除)和jqxBaseFramework。 所以現在我們告訴webpack,每當jqxknockout被加載時,它應該加載jqxcore模塊,並將其輸出分配給一個名爲「jqxBaseFramework」的模塊局部變量,並加載淘汰賽模塊並將其輸出分配給模塊局部變量「ko 」。 這實際上等同於將以下代碼預先添加到jqxknockout。js腳本:

var jqxBaseFramework = require("jqxcore"); 
var ko = require("knockout"); 

腳本現在可以再次執行,因爲找到了這兩個變量。 我添加了導出加載器來導出相同的,但現在處理/增強jqxBaseFramework變量從jqxknockout。

jqxSplitter通常只需要jqxCore工作,但我想總是用它來淘汰。所以我沒有從jqxSplitter的jqxCore中導入jqxBaseFramework,而是從jqxKnockout中獲得它,所以所有的部分都已經到位。 所以現在當我將此代碼添加到我在任何文件:

import "jqwidgets-framework/jqwidgets/jqxsplitter"; 

的WebPack需要jqxknockout和它的出口,是jqxBaseFramework,這反過來將需要jqxcore和基因敲除等瞧,整個事情精美地連接起來。

希望這可以幫助別人!