1.基础配置
1.1 library命名
如果我们打包的⽬的是⽣成⼀个供别⼈使⽤的库,那么可以使⽤ output.library 来指定库的名称,库
的名称⽀持占位符和普通字符串:
module.exports = {
output: {
library: 'myLib' // '[name]'
}
};
1.2 libraryTarget 打包规范
使⽤ output.library 确定了库的名称之后,还可以使⽤ output.libraryTarget 指定库打包出来的 规范, output.libraryTarget 取值范围
为: var 、 assign 、 this 、 window 、 global 、 commonjs 、 commonjs2 、 commonjs
module 、 amd 、 umd 、 umd2 、 jsonp ,默认是 var ,下⾯通过打包后的代码不同,来看下差别。
// var config
{
output: {
library: 'myLib',
filename: 'var.js',
libraryTarget: 'var'
}
}
// output
var myLib = (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
// ===============================================
// assign config
{
output: {
library: 'myLib',
filename: 'assign.js',
libraryTarget: 'assign'
}
}
// output: 少了个 var
myLib = (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
// ===============================================
// this config{
{
output: {
library: 'myLib',
filename: 'this.js',
libraryTarget: 'this'
}
}
// output
this["myLib"] = (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
// ===============================================
// window config
{
output: {
library: 'myLib',
filename: 'window.js',
libraryTarget: 'window'
}
}
// output
window["myLib"] = (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
// ===============================================
// global config
{
output: {
library: 'myLib',
filename: 'global.js',
libraryTarget: 'global'
}
}
// output:注意 target=node 的时候才是 global,默认 target=web下global 为 window
window["myLib"] = (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
// ===============================================
// commonjs config
{
output: {
library: 'myLib',
filename: 'commonjs.js',
libraryTarget: 'commonjs'
}
}
// output
exports["myLib"] = (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
// ===============================================
// amd config
{
output: {
library: 'myLib',
filename: 'amd.js',
libraryTarget: 'amd'
}
}
// output
define('myLib', [], function () {
return (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
});
// ===============================================
// umd config
{
output: {
library: 'myLib',
filename: 'umd.js',
libraryTarget: 'umd'
}
}
// output
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd) define([], factory);
else if (typeof exports === 'object') exports['myLib'] = factory();
else root['myLib'] = factory();
})(window, function () {
return (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
});
// ===============================================
// commonjs2 config
{
output: {
library: 'myLib',
filename: 'commonjs2.js',
libraryTarget: 'commonjs2'
}
}
//output
module.exports = (function(modules) {})({
'./src/index.js': function(module, exports) { }
});
// ===============================================
// umd2 config
{
output: {
library: 'myLib',
filename: 'umd2.js',
libraryTarget: 'umd2'
}
}
// output
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd) define([], factory);
else if (typeof exports === 'object') exports['myLib'] = factory();
else root['myLib'] = factory();
})(window, function () {
return (function (modules) { })({
'./src/index.js': function (module, exports) {
}
});
});
// ===============================================
// commonjs-module config
{
output: {
library: 'myLib',
filename: 'commonjs-module.js',
libraryTarget: 'commonjs-module'
}
}
// output
module.exports = (function (modules) { })({
'./src/index.js': function (module, exports) { }
});
// ===============================================
// jsonp config
{
output: {
library: 'myLib',
filename: 'jsonp.js',
libraryTarget: 'jsonp'
}
}
// output
myLib((function (modules) { })({
'./src/index.js': function (module, exports) { }
}));
// ===============================================
1.3 target
在项⽬开发中,我们不仅仅是开发 web 应⽤,还可能开发的是 Node.js 服务应⽤、或者 electron 这类 跨平台桌⾯应⽤,这时候因为对应的宿主环境不同,所以在构建的时候需要特殊处理。webpack 中可以 通过设置 target 来指定构建的⽬标(target)。
myLib((function (modules) { })({
'./src/index.js': function (module, exports) { }
}));
module.exports = {
target: 'web' // 默认是 web,可以省略
};
- target 的值有两种类型:string 和 function。
- string 类型⽀持下⾯的七种:
- web :默认,编译为类浏览器环境⾥可⽤;
- node :编译为类 Node.js 环境可⽤(使⽤ Node.js require 加载 chunk);
- async - node :编译为类 Node.js 环境可⽤(使⽤ fs 和 vm 异步加载分块);
- electron - main :编译为 Electron 主进程;
- electron - renderer :编译为 Electron 渲染进程;
- node - webkit :编译为 Webkit 可⽤,并且使⽤ jsonp 去加载分块。⽀持 Node.js 内置模块和
- nw.gui 导⼊(实验性质);
- webworker :编译成⼀个 WebWorker。
除了 string 类型,target 还⽀持 function 类型,这个函数接收⼀个 compiler 作为参数,如下⾯代 码可以⽤来增加插件:
const webpack = require('webpack');
const options = {
target: compiler => {
compiler.apply(new webpack.JsonpTemplatePlugin(options.output), new
webpack.LoaderTargetPlugin('web'));
}
};
2 实操
1.打包流程
- 新建⼀个library库项⽬
- 使用webpack打包两个版本⽂件,一个是压缩,一个是未压缩
- 发布到npm
- 项⽬引入使用
1.创建项目
// ⽬录结构
//dist 构建后文件夹
//src/index.js 库源码
export default function add(a, b) {
return a + b;
}
//index.js 程序main 入口
//可以根据当前不同的编译环境 导入不同的代码
if (process.env.NODE_ENV == "production") {//生产环境使用压缩后的
module.exports = require("./dist/add-number.min.js");
} else {
module.exports = require("./dist/add-number.js");
}
//package.json 配置信息
{
"name": "my-test-add",
"version": "1.1.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"terser-webpack-plugin": "^4.2.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12"
}
}
//webpack.config.js 打包信息
const TerserPlugin = require("terser-webpack-plugin"); //这里不实用
module.exports = {
entry: {
"add-number": "./src/index.js",
"add-number.min": "./src/index.js",
},
output: {
filename: "[name].js",
library: "addNumber",
libraryTarget: "umd",
libraryExport: "default", //这里需要声明,不然调用地方需要 再.default才能访问
},
mode: "none",
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.min\.js$/,
}),
],
},
};
- 使⽤terser来压缩 JavaScript 代码,是官方推荐的压缩代码。
- UglifyJS 在 ES6 代码压缩上做的不够好,代码也不再维护,terser是UglifyJS的分支,一直有维护。
2.2 使用命令npm构建
npm run build
2.3 发布到npm
- npm源的修改
- npm注册 官网注册 www.npmjs.com/signup
- npm登陆 npm login npm who am i (查看当前登陆用户)
- npm发布 :注意发布时候,是把整个项目所有文件除了node_modules,其他都上传
#!/usr/bin/env bash
npm config get registry # 检查仓库镜像库
npm config set registry=http://registry.npmjs.org # 恢复为官方的镜像
echo '请进行登录相关操作:'
npm login # 登陆
echo "-------publishing-------"
npm publish # 发布
npm config set registry=https://registry.npm.taobao.org # 设置为淘宝镜像
echo "发布完成"
exit
2.4 项⽬引入使用
由于my-test-add的 index.js 判断当前环境变量 是否 process.env.NODE_ENV == "production"
所以最终根据 当前项目 mode: "development"/"production" 引入不同的版本 add-number.js 或者 add-number.min.js
//webpack.config.js
const path = require("path")
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./dist"),
filename: "main.js",
},
mode: "development" //该变量影响实际打包使用的my-test-add库
};
//package.json
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"webpack": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"jasonyang-util-add": "1.0.0",
"webpack": "^5.10.0",
"webpack-cli": "^4.2.0"
}
}
//src/index.js
// //注意如果打包库 没有指定 output: { libraryExport: "default"},需要.default才能访问
//由于设置umd,import和requrie 都支持
//import 方式导入
import addNum from "my-test-add";
console.log(addNum(1, 2));
//requrie方式导入
const addNum = requrie("my-test-add") ;
console.log(addNum(1, 2));
//dist/main.js //这是打包编译后的文件
//dist/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
扩展
lerna 管理多个库