Webpack
webpack
内容概述
- 认识webpack
- webpack的安装
- webpack的起步
- webpack的配置
- loader的使用
- webpack中配置Vue
- plugin的使用
- 搭建本地服务器
- webpack的配置文件分离
一、什么是webpack?
- webpack是一个现代的JavaScript应用的静态模块打包工具。
- 前端模块化:
- webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系.
- 不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用.
- 打包
- 就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。
- 并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。
-
和grunt/gulp的对比
- grunt/gulp的核心是Task
- 我们可以配置一系列的task, 并且定义task要处理的事务(例如ES6、ts转化,图片压缩)
- 之后让gulp/grunt来依次执行这些task, 而且让整个流程自动化
- 所以grunt/gulp也被称为前端自动化任务管理工具
- 什么时候用grunt/gulp?
- 如果你的工程模块依赖非常简单, 甚至没有用到模块化的概念。
- 只需要进行简单的合并、压缩、就使用个grunt/gulp即可。
- 但是如果整个项目使用了模块化管理, 而且相互依赖非常强,我们就可以使用更加强大的webpack了。
- grunt/gulp和webpack的区别
- grunt/gulp更加强调前端流程的自动化, 模块化不是他的核心
- webpack更加强调模块化开发管理,二文件压缩合并、预处理等功能,是他附带的功能。
- grunt/gulp的核心是Task
二、webpack的安装
-
安装webpack首先需要安装Nodejs, Nodejs自带了软件包管理工具npm。
-
查看node版本
node -v
-
全局安装webpack(安装3.6.0版本)
npm install webpack@3.6.0 -g
-
局部安装webpack
-
cd 对应目录 npm install webpack@3.6.0 --save-dev
-
-
为什么全局安装之后,还需要局部安装
- 在终端直接执行webpack命令, 使用的全局安装的webpack
- 当在package.json中定义了scripts时, 其中包含了webpack命令, 那么使用的是局部webpack
三、webpack起步
3.1 准备工作
-
创建如下文件和文件夹:
-
文件和文件夹解析:
-
dist文件夹:用于存放之后打包的文件
-
src文件夹: 用于存放我们写的源文件
-
main.js: 项目的入口文件。
-
const { add, mul } = require('./mathUilsjf') console.log(add(20, 30)); console.log(mul(20, 30));
-
mathUtils.js: 定义了一些数学工具函数,可以再其他地方引用, 并且使用。
-
function add(num1, num2) { return num1 + num2 } function mul(num1, num2) { return num1 * num2 } module.exports = { add, mul }
-
index.html
-
package.json: 通过
npm init
生成, npm报管理的文件
-
-
-
使用webpack打包
-
webpack src/main.js dist/bundle.js
-
使用打包后的文件
- 打包后在dist文件下, 生成一个bundle.js文件
- bundle.js文件, 是webpack处理了项目直接文件依赖后生成的一个js文件, 我们只需要将这个js文件在index.html中引入即可
- 打包后在dist文件下, 生成一个bundle.js文件
3.2 webpack的配置
- 如果每次使用webpack的命令都需要写上入口和出口作为参数会很麻烦, 此时我们可以使用webpack配置
3.2.1 在根目录下创建一个webpack.config.js
文件
-
// 1.导入node的path包获取绝对路径, 需要使用npm int 初始化node包 const path = require('path') // 配置webpack的入口和出口 module.exports = { // 入口文件 entry: './src/main.js', // 出口: 通常是一个对象, 里面至少包含两个重要属性, path 和 filename output: { path: path.resolve(__dirname, 'dist'), // 动态获取打包后的文件路径,path.resolve拼接路径 filename: 'bundle.js' //打包后的文件名 } }
3.2.2 在根目录下npm init
初始化node包, 因为配置文件中用到node的path包
npm init
3.3.3 使用webpack打包
这样入口和出口的配置已经配置完成了, 只需要使用webpack
命令即可
3.3 使用自定义脚本(script)启动
-
目前, 我们使用的webpack是全局的webpack, 如果我们想使用局部来打包呢?
- 因为一个项目往往依赖特定的webpack版本, 全局的版本可能和这个项目的webpack版本不一致, 导出打包出现问题。
- 所以通常一个项目,都有自己局部的webpack
-
第一步,项目中需要安装自己局部的webpack
-
这里我们局部安装webpack@3.6.0
-
Vue CLI3中已经升级到webpack4,但是它将配置文件隐藏了起来,所以查看起来不是很方便。
-
npm i webpack@3.6.0 --save-dev
-
-
第二步, package.json中定义启动
-
在package.json的scripts中定义自己的执行脚本
-
package.json中的scripts的脚本在执行时, 会按照一定的顺序寻找命令对应的位置.
-
首先, 会寻找本地的node_modules/bin路径中对应的命令
-
如果没有找到, 会去全局的环境变量中寻找.
-
如何执行我们的build命令呢?
-
npm run build
-
-
四、loader
4.1 什么是loader
- loader是webpack中一个非常核心的概念
- webpack用来做什么呢?
- 在我们之前的实例中,我们主要是用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖。
- 但是,在开发中我们不仅仅有基本的js代码处理,我们也要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等
- 对于webpack本身的能力来说, 对于这些转化是不支持的
- 此时就需要webpack的扩展loader
- loader使用过程:
- 步骤一: 通过
npm
安装需要的loader - 步骤二: 在webpack.config.js中的module关键字下进行配置
- 步骤一: 通过
- 大部分loader在webpack官网都能找到对应的配置
4.2 CSS文件处理
-
新建一个css文件夹, 新建一个normal.css文件
-
body { background-color: red; }
-
main.js 导入依赖
-
require('./css/normal.css')
-
此时如果直接进行打包
npm run build
- 这时我们需要一个css-loader来处理css文件
-
安装css-loader
npm install --save-dev css-loader
-
使用css-loader
module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, 'dist'), //绝对路径 filename: 'bundle.js' }, module: { rules: [ { test: /\.css$/, use: ['css-loader'] } ] } }
-
执行
npm run build
,提示打包成功,但是背景色并没有变红色,是因为css-loader只负责加载css文件,不负责解析,如果要将样式解析到dom元素中需要使用style-loader。 -
安装使用style-loader
npm i --save-dev style-loader
module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, 'dist'), //绝对路径 filename: 'bundle.js' }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] } }
-
webpack使用多个loader是从右往左解析的,所以需要将css-loader放在style-loader右边,先加载后解析。
4.4 less文件处理
4.1在css文件夹下新增一个less文件(special.less)
@fontSize: 50px;
@fontColor: orange;
body {
font-size: @fontSize;
color: @fontColor;
}
4.2 在main.js中导入less文件
require('./css/special.less')
// 向页面写入一些内容
document.writeln('<h1>hello world</h1>')
4.3 安装使用less-loader
npm install --save-dev less-loader@4.1.0 less
4.4 在webpack.config.js
中配置less-loader
module: {
rules: [
{
test: /\.less$/,//正则表达式匹配css文件
//css-loader只负责css文件加载,不负责解析,要解析需要使用style-loader
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'less-loader'//less文件loader
}]//使用loader
}
]
}
4.5 npm run build
5. 图片文件处理
准备工作,准备两张图片,图片大小为一张8KB以下,一张大于8KB,新建一个img文件夹将两张图片放入。
5.1 修改normal.css样式,先使用小图片作为背景
body {
/*background-color: red;*/
background: url("../images/3.jpg");
}
- 此时如果直接使用npm run build 直接打包会报错,因为css文件中引用了图片url,此时需要使用url-loader。
5.2 安装使用url-loader
npm install --save-dev url-loader
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
}
}
]
}
]
}
}
5.3 打包npm run build
小于limit
大小的图片地址被编译成base64格式的字符串。
-
修改css文件, 使用大图片做背景
-
再次打包, 报错, 提示未找到file-loader模块
-
因为大于
limit
的图片需要file-loader
来打包。 -
安装file-loader
npm install --save-dev file-loader
-
不需要配置, 因为url-loader超过limit的图片会直接使用file-loader
-
再次打包, 没有报错, 打包成功, 但是图片未显示
-
当加载的图片大小小于limit,使用base64将图片编译成字符串
-
当加载的图片大小大于limit,使用file-loader模块直接将big.jpg直接打包到dist文件家,文件名会使用hash值防止重复。
-
此时由于文件路径不对所以导致没有加载到图片
-
-
修改output属性
output: { path: path.resolve(__dirname, 'dist'), //绝对路径 filename: 'bundle.js', publicPath: 'dist/' }
-
此时打包, 图片正常显示
5.4 图片文件处理 - 修改文件名称
在options中添加如下选项:
-
img: 文件要打包到的文件夹
-
name: 获取图片原来的名字, 放在改位置
-
hash:8: 为了防止图片名称冲突, 依然使用hash, 但是我们只保留8位
-
ext: 使用图片原来的扩展名
{ test: /\.(png|jpg|gif|jpeg)$/i, use: [{ loader: 'url-loader', options: { limit: 8192, name: 'img/[name].[hash:8].[ext]' } } ]}
6. ES6 语法处理
-
webpack打包时候ES6语法没有打包成ES5语法,如果需要将ES6打包成ES5语法,那么就需要使用
babe
l。直接使用babel对应的loader就可以了。 -
安装
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
-
配置
{ test: /\.js$/, //排除node模块的js和bower的js exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { //如果要使用@babel/preset-env这里需要在根目录新建一个babel的文件 // presets: ['@babel/preset-env'] //这里直接使用指定 presets: ['es2015'] } } }
-
如果要使用@babel/preset-env这里需要在根目录新建一个babel的文件
-
exclude排除不需要打包的文件
五、webpack中配置Vue
5.1 引入Vue
- 安装
npm i vue --save
-
注意: 注:因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖
-
在main.js导入已安装的vue, 并在index.html挂载div
import Vue from 'vue' new Vue({ el: '#app', data: { message: 'hello webpack' } })
-
修改index.html代码, 添加
<div id="app"> <h2>{{ message }}</h2> </div>
-
打包
npm run build
, 然后打开index.html- 发现message并没有正确显示,打开console发现vue报错。错误提示我们,正在使用
runtime-only
构建,不能将template模板编译。 -
runtime-only
模式,代码中不可以有任何template,因为无法解析。 -
runtime-complier
模式,代码中可以有template,因为complier可以用于编译template。
- 发现message并没有正确显示,打开console发现vue报错。错误提示我们,正在使用
-
在
webpack.config.js
中配置, 设置指定使用runtime-complier
模式
resolve: {
// alias:别名
alias: {
//指定vue使用vue.esm.js
'vue$':'vue/dist/vue.esm.js'
}
}
- 这次打包运行, 就可以了
5.2 如何分布抽取实现Vue模块
- 创建vue的template和el关系
- el表示挂载到DOM的挂载点
- template里面的html将替换挂载点
5.2.1 一般我们使用vue会开发单页面富应用SPA(single page application),只有一个index.html,而且index.html都是简单结构。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webpack入门</title>
</head>
<body>
<div id="app">
</div>
<script src="./dist/bundle.js"></script>
</body>
</html>
-
第一次抽取, 使用template替换
<div id="app"></div>
-
修改main.js的vue相关代码
//6.使用vue开发 import Vue from 'vue' new Vue({ el: "#app", template:` <div> <h2>{{message}}</h2> <button @click='btnClick'>这是一个按钮</button> <h2>{{name}}</h2> </div> `, data: { message: "hello webpack and vue", name: 'frontEnd' }, methods: { btnClick(){ console.log("按钮被点击了") } }, })
-
使用template模板替换挂载的id为app的div元素, 此时不需要修改html代码, 只需要写template
-
再次打包, 显示成功
-
-
第二次抽取, 写在template中, main.js的vue代码太太冗余。
-
修改main.js代码
//1.定义一个组件 const App = { template: ` <div> <h2>{{message}}</h2> <button @click='btnClick'>这是一个按钮</button> <h2>{{name}}</h2> </div> `, data() { return { message: "hello webpack and vue", name: 'frontEnd' } }, methods: { btnClick(){ console.log("按钮被点击了") } }, }
-
修改main.js, vue实例中注册组件, 并使用组件
new Vue({ el: "#app", //使用组件 template: '<App/>', components: { //注册局部组件 App } })
-
再次使用
npm run build
打包, 打包成功, 显示和使用template替换div一样
-
-
第三次抽取组件对象, 封装到新的js文件, 并使用模块胡导入main.js
- 此处我的vue-loader是15.7.2。
- 将其修改为13.0.0
- 重新安装版本
npm install
- 再次打包, 打包成功
5.3. 组件化开发
我们使用app.vue分离了模板、行为、样式,但是不可能所有的模板和样式都在一个vue文件内,所以要用组件化。
在vue文件夹下新建一个Cpn.vue文件
-
Cpn.vue组件
<template> <div> <h2 class='title'>{{name}}</h2> </div> </template> <script type="text/ecmascript-6"> export default { name: "Cpn", data() { return { name: "组件名字是Cpn" }; } }; </script> <style scoped> .title { color: red; } </style>
-
将Cpn.vue组件导入App.vue
<template> <div> <h2 class='title'>{{message}}</h2> <button @click="btnClick">按钮</button> <h2>{{name}}</h2> <!-- 使用Cpn组件 --> <Cpn/> </div> </template> <script type="text/ecmascript-6"> //导入Cpn组件 import Cpn from './Cpn.vue' export default { name: "App", data() { return { message: "hello webpack", name: "zzz" }; }, methods: { btnclick() {} }, components: { Cpn//注册Cpn组件 } }; </script> <style scoped> .title { color: green; } </style>
-
再次打包,打开index.html,cpn组件的内容显示
六、webpack的plugin
- plugin插件用于扩展webpack功能的扩展,例如打包时候优化,文件压缩。
- loader和plugin的区别
- loader主要用于转化某些类型的模块,是一个转化器
- plugin主要是对webpack本身的扩展, 是一个扩展器
- plugin的使用过程:
- 步骤一:通过npm安装需要使用的plugin(某些webpack已经内置的插件不需要安装)
- 步骤二: 在
webpack.config.js
中的plugins中配置插件。
6.1 添加版权的Plugin
-
为打包的文件添加版权声明, 使用BannerPlugin插件,属于webpack自带的插件
//获取webpack const webpack = require('webpack') //2.配置plugins module.exports = { ... plugins:[ new webpack.BannerPlugin('最终解释权归lucky-frontEnd所有') ] }
6.2 打包html的plugin
之前我们的index.html文件都是存放在根目录下的。
在正式发布项目的时候发布的是dist文件夹的内容,但是dist文件夹是没有index.html文件的,那么打包就没有意义了。
所以我们需要将index.html也打包到dist文件夹中,这就需要使用**HtmlWebpackPlugin
**插件了。
-
HtmlWebpackPlugin
:自动生成一个index.html文件(指定模板)
将打包的js文件,自动同script标签插入到body中
-
首先需要安装**
HtmlWebpackPlugin
**插件npm install html-webpack-plugin --save-dev
-
使用插件,修改webpack.config.js文件中的plugins部分
//获取htmlWebpackPlugin对象 const htmlWbepackPlugin = require('html-webpack-plugin') //2.配置plugins module.exports = { ... plugins:[ new webpack.BannerPlugin('最终解释权归lucky-frontEnd所有'), new htmlWbepackPlugin({ template: 'index.html' }) ] }
1.template表示根据哪个模板来生成index.html
2.需要删除output中添加的publicPath属性,否则插入的script标签的src可能有误
-
再次打包,打开dist文件夹,多了一个index.html
6.3压缩打包代码插件
-
uglifyjs-webpack-plugin是第三方插件,如果是vuecli2需要指定版本1.1.1。
-
安装:
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
-
配置plugin
//获取uglifyjs-webpack-plugin对象 const uglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') //2.配置plugins module.exports = { ... plugins:[ new webpack.BannerPlugin('最终解释权归lucky-frontEnd所有'), new htmlWbepackPlugin({ template: 'index.html' }), new uglifyjsWebpackPlugin() ] }
-
打包过后,打开bundle.js,发现已经压缩了,此时版权声明被删除了。
-
webpack高版本自带了压缩插件。
七、webpack搭建本地服务器
-
webpack提供了一个可选的本地服务器, 这个本地服务器基于nodejs搭建, 内部使用express框架, 可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。
-
不过它是一个单独的模块,在webpack中使用之前需要先安装它
npm install --save-dev webpack-dev-server@2.9.1
-
devServe也是webpack中一个选项,选项本省可以设置一些属性:
- contentBase:为哪个文件夹提供本地服务,默认是根文件夹,这里我们需要改成./dist
- port: 端口号
- Inline: 页面实时刷新
- historyApiFallback:在SPA(单页面富应用)页面中,依赖HTML5的history模式
-
修改webpack.config.js的文件配置
//2.配置webpack的入口和出口 module.exports = { ... devServer: { contentBase: './dist',//服务的文件夹 port: 4000, inline: true//是否实时刷新 } }
-
配置package.json的script:
"dev": "webpack-dev-server --open"
-
启动服务器
npm run dev
-
启动成功,自动打开浏览器,发现在本地指定端口启动了,此时你修改src文件内容,会热修改。
-
服务器启动在内存中。
-
开发调试时候最好不要使用压缩js文件的插件,不易调试。
-
八、webpack的配置文件分离
-
webpack.config.js
文件中有些是开发时候需要配置,有些事生产环境发布编译需要的配置,比如搭建本地服务器的devServer配置就是开发时配置,接下来我们分析如何分离配置文件。 -
在根目录下新建一个
build
的文件夹,新建配置文件。-
base.config.js(公共的配置)
//1.导入node的path包获取绝对路径,需要使用npm init初始化node包 const path = require('path') //获取webpack const webpack = require('webpack') //获取htmlWebpackPlugin对象 const htmlWbepackPlugin = require('html-webpack-plugin') //2.配置webpack的入口和出口 module.exports = { entry: './src/main.js',//入口文件 output:{ path: path.resolve(__dirname, 'dist'),//动态获取打包后的文件路径,path.resolve拼接路径 filename: 'bundle.js',//打包后的文件名 // publicPath: 'dist/' }, module: { rules: [ { test: /\.css$/,//正则表达式匹配css文件 //css-loader只负责css文件加载,不负责解析,要解析需要使用style-loader use: [{ loader: 'style-loader' }, { loader: 'css-loader' }]//使用loader }, { test: /\.less$/,//正则表达式匹配css文件 //css-loader只负责css文件加载,不负责解析,要解析需要使用style-loader use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'less-loader'//less文件loader }]//使用loader }, { test: /\.(png|jpg|gif)$/,//匹配png/jpg/gif格式图片 use: [ { loader: 'url-loader', options: { limit: 8192,//图片小于8KB时候将图片转成base64字符串,大于8KB需要使用file-loader name: 'img/[name].[hash:8].[ext]'//img表示文件父目录,[name]表示文件名,[hash:8]表示将hash截取8位[ext]表示后缀 } } ] }, { test: /\.js$/, //排除node模块的js和bower的js exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { //如果要使用@babel/preset-env这里需要在根目录新建一个babel的文件 // presets: ['@babel/preset-env'] //这里直接使用指定 presets: ['es2015'] } } }, { test: /\.vue$/,//正则匹配.vue文件 use: { loader: 'vue-loader' } } ] }, resolve: { // alias:别名 alias: { //指定vue使用vue.esm.js 'vue$':'vue/dist/vue.esm.js' } }, plugins:[ new webpack.BannerPlugin('最终解释权归lucky-frontEnd所有'), new htmlWbepackPlugin({ template: 'index.html' }) ] }
-
prod.config.js(构建发布时候需要的配置)
const uglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') module.exports = { plugins:[ new uglifyjsWebpackPlugin() ] }
-
-
此时我们将
webpack.config.js
文件分成了三个部分,公共部分、开发部分、构建发布的部分。- 如果此时是dev环境,我们只需要使用
base.config.js
+dev.config.js
的内容 - 如果此时是生产发布构建的环境,我们只需要使用
base.config.js
+prod.config.js
的内容
- 如果此时是dev环境,我们只需要使用
-
要将两个文件内容合并需要使用
webpack-merge
插件,安装webpack-merge
。npm isntall webpack-merge --save-dev
-
修改dev.config.js
//导入webpack-merge对象 const webpackMerge = require('webpack-merge') //导入base.config.js const baseConfig = require('./base.config') //使用webpackMerge将baseConfig和dev.config的内容合并 module.exports = webpackMerge(baseConfig, { devServer: { contentBase: './dist',//服务的文件夹 port: 4000, inline: true//是否实时刷新 } })
-
修改prod.config.js
const uglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') //导入webpack-merge对象 const webpackMerge = require('webpack-merge') //导入base.config.js const baseConfig = require('./base.config') //使用webpackMerge将baseConfig和prod.config的内容合并 module.exports = webpackMerge(baseConfig, { plugins:[ new uglifyjsWebpackPlugin() ] })
-
此时我们使用三个文件构成了配置文件,此时在不同环境使用不同的配置文件,但是webpack不知道我们新配置文件,此时我们需要在package.json中的script指定要使用的配置文件。
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --config ./build/prod.config.js", "dev": "webpack-dev-server --open --config ./build/dev.config.js" }
-
此时使用
npm run build
打包文件,dist文件并不在根目录下,因为我们在base.config.js
中配置的出口文件使用的是当前文件的路径,即打包的根路径是配置文件的当前路径,也就是build文件夹。entry: './src/main.js',//入口文件 output:{ path: path.resolve(__dirname, 'dist'),//动态获取打包后的文件路径,path.resolve拼接路径 filename: 'bundle.js',//打包后的文件名 // publicPath: 'dist/' }
注意:__dirname是当前文件路径,path.resolve拼接路径,所以在当前路径下创建了一个dist文件夹。
-
此时修改output属性:
output:{ path: path.resolve(__dirname, '../dist'),//动态获取打包后的文件路径,path.resolve拼接路径 filename: 'bundle.js',//打包后的文件名 // publicPath: 'dist/' }
使用
../dist
,在当前目录的上级目录创建dist文件夹plugins:[
new uglifyjsWebpackPlugin()
]
}) -
此时我们使用三个文件构成了配置文件,此时在不同环境使用不同的配置文件,但是webpack不知道我们新配置文件,此时我们需要在package.json中的script指定要使用的配置文件。
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --config ./build/prod.config.js", "dev": "webpack-dev-server --open --config ./build/dev.config.js" }
-
此时使用
npm run build
打包文件,dist文件并不在根目录下,因为我们在base.config.js
中配置的出口文件使用的是当前文件的路径,即打包的根路径是配置文件的当前路径,也就是build文件夹。entry: './src/main.js',//入口文件 output:{ path: path.resolve(__dirname, 'dist'),//动态获取打包后的文件路径,path.resolve拼接路径 filename: 'bundle.js',//打包后的文件名 // publicPath: 'dist/' }
注意:__dirname是当前文件路径,path.resolve拼接路径,所以在当前路径下创建了一个dist文件夹。
-
此时修改output属性:
output:{ path: path.resolve(__dirname, '../dist'),//动态获取打包后的文件路径,path.resolve拼接路径 filename: 'bundle.js',//打包后的文件名 // publicPath: 'dist/' }
使用
../dist
,在当前目录的上级目录创建dist文件夹
本文地址:https://blog.csdn.net/weixin_47085255/article/details/107240553