准备
新建项目目录,然后执行命令生成package.json
文件:
npm init -y
将package.json
里scripts
改为如下代码:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --mode development",
"build": "webpack --mode production"
},
src
为我们源代码目录,dist
为打包后文件存放目录,node-modules
为webpack
以及项目所需要的依赖包目录。
搭建webpack
开发环境以及安装其插件:执行如下命令:
npm i clean-webpack-plugin --save-dev
打包时清除以前打包的文件
npm i css-loader --save-dev
加载编译css
的loader
npm i html-webpack-plugin --save-dev
打包后自动生成.html
文件及在此文件自动引入js
和css
npm i mini-css-extract-plugin --save-dev
将css
从打包的js
中分离出来,写入css
文件中。
npm i webpack-dev-server --save-dev
webpack
开发环境
npm i webpack webpack-cli --save-dev
webpack
打包工具
npm i jquery --save
以npm
的形式安装jquery
以上安装成功后,package.json
会添加如下图的依赖字段
然后,我们在项目src
目录下新建index.html
和入口起点文件index.js
。配置webpack.config.js
package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --mode development",
"build": "webpack --mode production"
},
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^2.0.1",
"css-loader": "^2.1.1",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.5.0",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1"
},
"dependencies": {
"jquery": "^3.3.1"
}
}
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin =require('mini-css-extract-plugin');
const config = {
optimization: {
splitChunks: {
cacheGroups: {
commons: {
chunks: "initial",
name: "common",
minChunks: 2,
maxInitialRequests: 5,
minSize: 0
}
}
}
},
entry: {
index:"./src/index.js"
},
output: {
path: path.resolve(__dirname,"dist"),
filename: "[name].js",
publicPath: "/",
chunkFilename: "[name].chunk.js"
},
module: {
rules: [
{
test:/\.css$/,
use:[
{
loader:MiniCssExtractPlugin.loader,
options: {
publicPath:"/"
}
},
"css-loader"
]
}
]
},
devServer: {
contentBase: path.resolve(__dirname,'dist'),
host:"localhost",
port:8080,
open: true,
hot: true,
},
resolve:{
alias: {
cssPath:path.resolve(__dirname,'src/css'),
}
},
plugins: [
new MiniCssExtractPlugin({
filename:"[name].css",
chunkFilename: "common.css"
}),
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
filename:"index.html",
template:"./src/index.html",
hash:true
})
]
};
module.exports = config;
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>引入jquery</title>
</head>
<body>
<div>
<button type="button" id="btn-alert" >点我 alert</button><br>
<button type="button" id="btn-layer" >点我 layer</button>
</div>
执行npm run dev
,浏览器自动打开http://localhost:8080/
。运行成功。
使用 ProvidePlugin
ProvidePlugin
是一个webpack
插件,用于自动加载某一模块,当一个项目很多地方都使用同一模块时,这个插件可以省去多个地方写import/require
。不过,他在引入第三方库时也非常有用。
在webpack.config.js
里添加:const webpack = require('webpack');
然后在其Plugins
字段里添加:
plugins: [
//...
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',
});
]
//...
表示的意思是:当打包时遇到不能识别的$
、jQuery
、window.jQuery
、window.$
webpack就自动去加载jquery
模块。
在src
目录,我们新建一个sayHello.js
的文件,代码如下:
$.fn.sayHello = function () {
alert('Hello')
};
是一个简单的jquery
插件。
在index.js
文件里,编写如下代码
require('./sayHello.js');
$(function () {
$("#btn-alert").click(function () {
alert("alert弹出")
});
$('#btn-layer').click(function () {
$(this).sayHello()
});
});
执行npm run dev
,分别点击按钮,正常运行。
使用 expose-loader
expose
寓意为:暴露,expose-loader
为了解决一些不支持使用模块方式引入插件的问题,将这些插件导出的变量暴露为全局变量。
将上面我们使用ProvidePlugin
插件引入的代码删除,然后执行:
$ npm install expose-loader --save-dev
在webpack.config.js
的rules
里添加如下代码:
{
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: 'jQuery'
},{
loader: 'expose-loader',
options: '$'
}]
}
require.resolve('jquery')
表示在引入npm
包中jquery
时所用的规则。使用expose-loader
把jQuery
和$
暴露为全局变量。
然后我们在index.js
里使用如下方式引入jqury
:
require("expose-loader?$!jquery");
index.js
require("expose-loader?$!jquery");
require('./sayHello');
$(function () {
$("#btn-alert").click(function () {
alert("alert弹出")
});
$('#btn-layer').click(function () {
$(this).sayHello()
});
});
测试,运行成功。
前面说到的两种方法比较适合于引入jquery
的npm
包,下面我们来看看对于页面直接使用<script>
引入jquery
的情况。
使用 externals
首先,把项目恢复到初始状态(删除expose-loader
相关的设置),并且删除clean-webpack-plugin
。
externals
是webpack
配置中的一项,用来将某个全局变量“伪装”成某个js
模块的exports
。配置如下:
externals: {
jquery: 'jQuery'
}
表示,这个里面的jquery
是指require('jquery')
中的jquery
。webpack
在打包的时候,不用将require('jquery')
引入打依赖打包,而是在运行时,从外部取得jQuery
来作为其依赖,例如import $ from 'jquery';
当请求jquery
时,就取外部的jQuery
来作为导入到$
。
然后我们在页面里直接引入jquery
<script src="http://www.tensweets.com/script/jquery-3.3.1.min.js"></script>
index.js
require('jquery');
require('./sayHello');
$(function () {
$("#btn-alert").click(function () {
alert("alert弹出")
});
$('#btn-layer').click(function () {
$(this).sayHello()
});
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>引入jquery</title>
</head>
<body>
<div>
<button type="button" id="btn-alert" >点我 alert</button><br>
<button type="button" id="btn-layer" >点我 layer</button>
</div>
<script src="http://www.tensweets.com/script/jquery-3.3.1.min.js"></script>
</body>
</html>
jquery.vendor
这里是另一种通过npm
包引入jquery
方式,新建一个jquery.vendor.js
的文件,代码如下:
const $ = require('jquery');
window.$ = $;
window.jQuery = $;
module.exports = $;
然后在index.js
文件里引入此文件
index.js
require('./jquery.vendor.js');
require('./sayHello');
$(function () {
$("#btn-alert").click(function () {
alert("alert弹出")
});
$('#btn-layer').click(function () {
$(this).sayHello()
});
});
不过,怎么看怎么low
,跟expose-loader
相似。
以上方式,我们能引入jquery
(或npm
包或页面加载jquery
)以及用webpack来加载jQuery插件。
综上所述可以看除引入jquery
,其实就是要保证我们的代码或插件能取到变量$
、jQuery
的值。jquery
可以从外部或npm包载入,插件也如此,我们就以简单的内和外来区分吧。
1、 插件在内
- jquery在内:使用
ProvidePlugin
,让webpack
遇到代码和jquery插件中的$
、jQuery
变量就载入npm
包中的jquery
,确保了变量能找到值。也可以使用expose-loader
,把从npm
包中载入的jquery
暴露为全局变量,从而确保变量能找到值。 - jquery在外:页面加载了
jquery
后,全局会有$
、jQuery
变量,从而确保变量能找到值。这里似乎externals
有点多事,externals
可以根据外部依赖的类型可以将更深层次的数据“伪装”成某个js模块。
2、 插件在外
- jquery在内:使用
expose-loader
把$
、jQuery
暴露为全局,不过,这里得注意引入插件与暴露全局的顺序。 - jquery在外:使用
expose-loader
把$
、jQuery
暴露为全局,插件在jquery
后面载入即可。