首先贴一下 package.json中的插件版本,不同的版本也许会有很大的差异:
// package.json
{ "name": "WEBPACK-DEV-1", "version": "1.0.0", "main": "index.js", "license": "MIT", "scripts": { "dev": "webpack-dev-server", "build": "webpack --config webpack.config.js" }, "devDependencies": { "@babel/core": "^7.14.6", "@babel/preset-env": "^7.14.5", "autoprefixer": "^8.0.0", "babel-loader": "^8.2.2", "css-loader": "^5.2.6", "expose-loader": "0.7.5", "html-webpack-plugin": "^4.2.1", "less": "^4.1.1", "less-loader": "^6.1.0", "mini-css-extract-plugin": "^1.6.0", "optimize-css-assets-webpack-plugin": "^4.0.0", "postcss-loader": "^4.0.4", "style-loader": "^2.0.0", "uglifyjs-webpack-plugin": "^2.2.0", "webpack": "^4.28.2", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.11.2" }, "dependencies": { "jquery": "^3.6.0" } }
拿jquery为例子,使用 yarn add jquery -S 安装jquery到项目里面,这时候可以通过require("jquery")来获取,但是使用window.jquery仍然是undefined,那么如何把jquery挂在全局变量window(浏览器环境)上呢?
在 webpack.config.js 的 module.rules 里面添加如下配置对象即可,然后引用的话就可以直接用了
// webpack.config.js
{ test: require.resolve('jquery'), use:'expose-loader?$'
},
// index.js var $ = require("jquery"); console.log('$,',$) // expore-loader 暴露 全局的loader 内联的loader // loader[pre:前面执行的loader,normal:普通的loader,liader:内联的loader,postloader:后置loader] // 问:什么叫做内联的loader? // 答:var $ = require("expose-loader?$!jquery");希望把jquery暴露出去,暴露为"$",暴露给全局上 console.log('内联window.$,',window.$)
完整webpack配置:
var path = require('path'); let HtmlWebpackPlugin = require('html-webpack-plugin') let MiniCssExtractPlugin = require('mini-css-extract-plugin'); let OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');//压缩.css文件 let UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');//压缩js module.exports = { optimization:{//优化项 minimizer:[ new OptimizeCssAssetsWebpackPlugin(), new UglifyjsWebpackPlugin({ cache:true,//启用缓存 parallel:true,//并发打包 sourceMap:true }) ] }, mode: "production",//模式:production/development entry: './src/index.js', output: { filename: "bundle.[hash:6].js", // 可以指定打包后的文件名不同,bundle.[hash:6].js 可以指定hash的长度 path: path.resolve(__dirname, 'build'),//路径必须是绝对路径 }, devServer: { //开发服务配置 port: 3000,//端口 progress: true,//显示进度 contentBase: './build', //静态服务运行目录 compress: true,//压缩 }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", minify: { removeAttributeQuotes: true,//把index.html双引号转化为单引号 collapseWhitespace: true,//折叠空行 }, hash: true,//文件添加hash戳,防止服务器环境缓存,比如apach或者nginx }), new MiniCssExtractPlugin({ filename: 'main.css',// 抽离出来的样式文件 }) ],//webpack插件 module: { rules: [ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:[ // 预设 "@babel/preset-env" ] } } }, { test: require.resolve('jquery'), use:'expose-loader?$' }, // 解析css,css-loader 主要负责解析@import.style-loader 把 css 插入到 head标签中 // loader 用法: 字符串 // 多个loader:数组,loader有顺序,从右向左执行 // { // test: /\.css$/, use: [{ // loader: 'style-loader', // options: { // insert: function insertAtTop(element) { // var parent = document.querySelector('head'); // // eslint-disable-next-line no-underscore-dangle // var lastInsertedElement = // window._lastElementInsertedByStyleLoader; // if (!lastInsertedElement) { // parent.insertBefore(element, parent.firstChild); // } else if (lastInsertedElement.nextSibling) { // parent.insertBefore(element, lastInsertedElement.nextSibling); // } else { // parent.appendChild(element); // } // // eslint-disable-next-line no-underscore-dangle // window._lastElementInsertedByStyleLoader = element; // }, // } // }, 'css-loader'] // }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' ] } ] } }
一定要注意版本!!!