2016-05-17 24 views
7

Tôi đã tìm thấy một số câu hỏi StackOverflow liên quan đến điều này nhưng không có câu hỏi nào phù hợp hoặc cũng không khắc phục được sự cố của tôi.Nhập mô-đun kiểu UMD với ES6, Webpack và Babel

Tôi đang viết một thư viện trong ES6 được dự định sẽ được sử dụng trong trình duyệt và trên máy chủ. Tôi đã tìm thấy một số thư viện yêu cầu HTTP có thể sử dụng trên máy chủ hoặc trình duyệt (popsicle, axios). Tôi đã sử dụng thành công các thư viện này ở cả hai nơi nhưng có một số vấn đề khi nhập chúng vào nguồn của tôi và sử dụng tệp webpacked đã xuất.

My ES6 nguồn tập tin mà tôi đang nhập khẩu các thư viện axios

import axios from 'axios'; 

export default { 
    go: function() { 
     return axios.get('http://www.google.com'); 
    } 
}; 

webpack cấu hình của tôi là

var webpack = require('webpack'); 
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin; 
var WebpackNotifierPlugin = require('webpack-notifier'); 
var path = require('path'); 
var env = require('yargs').argv.mode; 

var libraryName = 'library'; 
var source = '/src/test.js'; 

var plugins = [], 
    outputFile; 

if (env === 'build') { 
    plugins.push(new UglifyJsPlugin({ 
     minimize: true 
    })); 
    outputFile = libraryName + '.min.js'; 
} else { 
    outputFile = libraryName + '.js'; 
    plugins.push(new WebpackNotifierPlugin()) 
} 

var config = { 
    entry: __dirname + source, 
    devtool: 'source-map', 
    output: { 
     path: __dirname + '/lib', 
     filename: outputFile, 
     library: libraryName, 
     libraryTarget: 'umd', 
     umdNamedDefine: true 
    }, 
    externals: {}, 
    module: { 
     loaders: [{ 
      test: /(\.jsx|\.js)$/, 
      loader: 'babel', 
      exclude: /(node_modules|bower_components)/ 
     }, { 
      test: /(\.jsx|\.js)$/, 
      loader: "eslint-loader", 
      exclude: /node_modules/ 
     }] 
    }, 
    resolve: { 
     root: path.resolve('./src'), 
     extensions: ['', '.js'] 
    }, 
    plugins: plugins 
}; 

module.exports = config; 

Như bạn có thể thấy tôi đang thiết lập các libraryTarget để umd và umdNamedDefine để true

.bablerc của tôi là

{ 
    "presets": ["es2015"], 
    "plugins": ["add-module-exports", "babel-plugin-add-module-exports"] 
} 

Tôi có thể sử dụng thư viện của mình trong trình duyệt bằng cách đưa nó vào thẻ script nhưng tôi không thể sử dụng thẻ khi nhập bằng nút. Tôi nhận được XMLHttpRequest is not defined. Thư viện trục nói rằng nó sử dụng XMLHttpRequest khi trên trình duyệt và http khi chạy trong nút nhưng vì một số lý do nó không phát hiện nó đang được chạy trên máy chủ. Tôi đang gặp vấn đề này với một vài thư viện UML vì vậy tin rằng nó không phải là gói cụ thể. Ngoài ra, kể từ khi tôi có thể sử dụng các thư viện này trong nút ES5 mà không cần chạy webpack hoặc babel, tôi đã dẫn đến giả sử nó là một vấn đề cấu hình với webpack.

Làm cách nào để nhập các thư viện kiểu UMD này trong ES6 và tạo thư viện với Webpack và Babel có thể được sử dụng trên máy chủ và trình duyệt?

+0

Bạn không nên sử dụng Webpack ở phía máy chủ. Đó là cốt lõi của vấn đề của bạn và không liên quan đến ES6 hoặc Babel hoặc bất kỳ điều gì khác mà bạn đã đề cập. Hãy thử mà không cần Webpack. – blakeembrey

+1

Nhưng sau đó làm thế nào tôi nên tạo thư viện được rút gọn mà sau đó tôi có thể xuất bản lên npm? –

+2

Bạn không. Đó là một thực tế khủng khiếp. Nút không cần các tệp được rút gọn, các trình duyệt sẽ thực hiện. Rút gọn là một công việc cho các nhóm. Có nhiều lý do cho điều này, nhưng đối với một - bạn đang chọn không tham gia phiên bản và phụ thuộc (bạn không thể dedupe ngay bây giờ). Tất nhiên, bạn có thể sử dụng Webpack cho nút-mã, nhưng hãy chắc chắn rằng bạn kích hoạt chế độ nút đầu tiên. Bạn sẽ phải tìm kiếm nó mặc dù. – blakeembrey

Trả lời

0

Để làm cho gói của bạn càng nhỏ càng tốt, tôi khuyên bạn nên sử dụng API tìm nạp. Một thư viện UMD có ba loại người tiêu dùng nơi tìm nạp có ích;

  • Node.js - đã không được thực hiện nhưng có thể sử dụng nút nạp để polyfill hành vi phổ biến chỉ sử dụng thư viện nút (không phụ thuộc nặng như superagent, unirest và Axios vv - những thêm an ninh liên quan đến cũng như sưng lên !).
  • Browser - Fetch là một tiêu chuẩn WHATWG và là sẵn trong hầu hết các trình duyệt hiện đại nhưng có thể yêu cầu một gói NPM như whatwg-fetch để polyfill trình duyệt cũ
  • đẳng cấu/Universal - cùng javascript chạy trong Node.js trình duyệt và mà bạn tìm thấy trong các ứng dụng web tiến bộ. Họ cần phải sử dụng thư viện được gọi là tìm nạp đẳng thức để tải hoặc tìm nạp whatwg hoặc phiên bản tìm nạp node.js.

Nó nên được xử lý bởi người tiêu dùng dự án mặc dù vậy README nên bao gồm hướng dẫn cho từng loại trong số ba loại người dùng ở trên.

Hướng dẫn Node.js và đẳng hướng về cơ bản như sau.

require(‘node-fetch’); // or require(‘isomorphic-fetch’) 
const MyUMDLibrary = require('my-umd-library'); 
const myUMDLibrary = new MyUMDLibrary(); 

Đối với trình duyệt sử dụng tập lệnh từ cdn, họ cũng có thể tải một vùng tìm nạp trước https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.js.

Tôi khuyên bạn nên sử dụng rollup cho thư viện UMD (see a working example I've contributed before for a UMD library) nhưng Webpack cũng không phải là vấn đề. Thay vì cố gắng bao gồm sự phụ thuộc 'axios' trong ứng dụng của bạn với Tìm nạp, bạn có thể bỏ qua và cho phép người dùng của bạn quyết định cách họ sẽ tải gói (tức là trình tải mô-đun, tập lệnh, yêu cầu).

Các vấn đề liên quan