Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack中library和libraryTarget与externals的使用 #10

Closed
zhengweikeng opened this issue Mar 24, 2016 · 15 comments
Closed

webpack中library和libraryTarget与externals的使用 #10

zhengweikeng opened this issue Mar 24, 2016 · 15 comments
Labels

Comments

@zhengweikeng
Copy link
Owner

在看webpack文档的LIBRARY AND EXTERNALS一节时,对output.libraryTarget和output.library还有externals总是无法理解,于是在segmentFault提问后结合实践总算多少理解它是怎么用的。

externals

官网文档解释的很清楚,就是webpack可以不处理应用的某些依赖库,使用externals配置后,依旧可以在代码中通过CMD、AMD或者window/global全局的方式访问。

怎么理解呢?我们先通过官网说的那个jquery的案例来理解。

有时我们希望我们通过script引入的库,如用CDN的方式引入的jquery,我们在使用时,依旧用require的方式来使用,但是却不希望webpack将它又编译进文件中。

<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>

jquery的使用如下

// 我们不想这么用
// const $ = window.jQuery

// 而是这么用
const $ = require("jquery")
$("#content").html("<h1>hello world</h1>")

这时,我们便需要配置externals

module.exports = {
  ...
  output: {
    ...
    libraryTarget: "umd"
  },
  externals: {
    jquery: "jQuery"
  },
  ...
}

我们可以看看编译后的文件

({
  0: function(...) {
    var jQuery = require(1);
    /* ... */
  },
  1: function(...) {
    // 很明显这里是把window.jQuery赋值给了module.exports
    // 因此我们便可以使用require来引入了。
    module.exports = jQuery;
  },
  /* ... */
});

我们自己可以写个例子,当然这个例子没什么实际意义,只是为了演示如何使用而已。

假设我们自己有个工具库,tools.js,它并没有提供给我们UMD的那些功能,只是使用window或者global的方式把工具的对象tools暴露出来

window.Tools = {
  add: function(num1, num2) {
    return num1 + num2
  }
}

接下来把它放在任何页面能够引用到的地方,例如CDN,然后用script的方式引入页面

<script src="http://xxx/tools.min.js"></script>

一般来说我们可能会直接就这么用了

const res = Tools.add(1,2)

但是既然我们是模块化开发,当然要杜绝一切全局变量了,我们要用require的方式。

const tools = require('mathTools')
const res = tools.add(1,2)

这是我们再来配置一些externals即可

module.exports = {
  ...
  output: {
    ...
    libraryTarget: "umd"
  },
  externals: {
    mathTools: "tools"
  },
  ...
}

关于externals的配置

首先是libraryTarget的配置,我们上面的例子都是umd
当然它还有其他配置方式,具体就看官网文档吧,我们可以看到配置成umd便可以使用任何一种引入的方式了

library和libraryTarget使用场景

接下来我们来说说library和libraryTarget的使用场景。

有些时候我们想要开发一个库,如lodash、underscore这些,这些库既可以用commonjs和amd的方式使用,也可以通过script标签的方式引入使用,目前很多库都是支持这几种使用方式的。

这时候我们就可以使用library和libraryTarget了,我们只需要用用es6的方式写代码,如何编译成umd就交给webpack了。

还是上面那个tools的例子

exports default {
  add: function(num1, num2) {
    return num1 + num2
  }
}

接下来配置webpack

module.exports = {
  entry: { myTools: "./src/tools.js" },
  output: {
    path: path.resolve(__dirname, "build"),
    filename: '[name].js',
    chunkFilename: "[name].min.js",
    libraryTarget: "umd",
    library: "tools"
  }
}

library指定的就是你使用require时的模块名,这里便是require("tools")
通过配置不同的libraryTarget会生成不同umd的代码,例如可以只是commonjs标准的,也可以是指amd标准的,也可以只是通过script标签引入的。

开发测试之后,便可以发布到npm给别人使用了。

@lewis-geek
Copy link

终于理解externals的用法了,感谢

@alcat2008
Copy link

解惑了,大赞一个

@superNever
Copy link

superNever commented Oct 26, 2016

可以将js按照文件夹单独打包出来吗?就像gulp那样可以按照文件夹结构单独打包js @zhengweikeng

@zhengweikeng
Copy link
Owner Author

@superNever 这个我还真不清楚。

webpack可以定义多个entry,每个entry文件放到指定的目录。

@yinjun1991
Copy link

文中

externals: {
  mathTools: "tools"
},

应该是

externals: {
  mathTools: "Tools"
},

key 是 require 的包名,value 是全局的变量。

@emthink
Copy link

emthink commented Jan 13, 2017

上文libraryTarget实例中只有一个Tools模块:
···

library: "Tools"

···
但是如果存在多个模块,如何处理呢?

@wlxscn
Copy link

wlxscn commented May 10, 2017

请问一下externals指定的依赖只能通过外部cdn引入吗,能放在项目中吗

@carbrokers
Copy link

明白了,感谢

@LiuYashion
Copy link

好棒,感谢~

@muxing92
Copy link

muxing92 commented Feb 5, 2018

thank you so much!!!

@carbrokers
Copy link

感谢分享

@isoloist
Copy link

thanks

@alsotang
Copy link

@codingplayboy 一个项目按理说就是只能暴露出一个模块啊。一个npm包也只能有一个入口嘛。

@emthink
Copy link

emthink commented May 26, 2018

@alsotang 可能是我之前理解有点问题,应该是libraryTarget是用来开发npm库/包的,实际开发项目/产品代码配置应该不会用吧。

@alsotang
Copy link

alsotang commented May 27, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests