安装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
为什么全局安装之后,还需要局部安装
创建如下文件和文件夹:
文件和文件夹解析:
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
}
package.json: 通过npm init
生成, npm报管理的文件
使用webpack打包
webpack src/main.js dist/bundle.js
使用打包后的文件
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' //打包后的文件名
}
}
npm init
初始化node包, 因为配置文件中用到node的path包npm init
这样入口和出口的配置已经配置完成了, 只需要使用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
npm
安装需要的loader新建一个css文件夹, 新建一个normal.css文件
body {
background-color: red;
}
main.js 导入依赖
require('./css/normal.css')
此时如果直接进行打包npm run build
安装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右边,先加载后解析。
@fontSize: 50px;
@fontColor: orange;
body {
font-size: @fontSize;
color: @fontColor;
}
require('./css/special.less')
// 向页面写入一些内容
document.writeln('<h1>hello world</h1>')
npm install --save-dev less-loader@4.1.0 less
webpack.config.js
中配置less-loadermodule: {
rules: [
{
test: /\.less$/,//正则表达式匹配css文件
//css-loader只负责css文件加载,不负责解析,要解析需要使用style-loader
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'less-loader'//less文件loader
}]//使用loader
}
]
}
npm run build
准备工作,准备两张图片,图片大小为一张8KB以下,一张大于8KB,新建一个img文件夹将两张图片放入。
body {
/*background-color: red;*/
background: url("../images/3.jpg");
}
npm install --save-dev url-loader
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
}
}
]
}
]
}
}
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/'
}
此时打包, 图片正常显示
在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]'
}
}
]}
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排除不需要打包的文件
npm i vue --save
注意: 注:因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖
在main.js导入已安装的vue, 并在挂载div
import Vue from 'vue'
new Vue({
el: '#app',
data: {
message: 'hello webpack'
}
})
修改代码, 添加
<div id="app">
<h2>{{ message }}</h2>
</div>
打包npm run build
, 然后打开
runtime-only
构建,不能将template模板编译。runtime-only
模式,代码中不可以有任何template,因为无法解析。runtime-complier
模式,代码中可以有template,因为complier可以用于编译template。在webpack.config.js
中配置, 设置指定使用runtime-complier
模式
resolve: {
// alias:别名
alias: {
//指定vue使用vue.esm.js
'vue$':'vue/dist/vue.esm.js'
}
}
<!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
npm install
我们使用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>
再次打包,打开,cpn组件的内容显示
webpack.config.js
中的plugins中配置插件。为打包的文件添加版权声明, 使用BannerPlugin插件,属于webpack自带的插件
//获取webpack
const webpack = require('webpack')
//2.配置plugins
module.exports = {
...
plugins:[
new webpack.BannerPlugin('最终解释权归lucky-frontEnd所有')
]
}
之前我们的文件都是存放在根目录下的。
在正式发布项目的时候发布的是dist文件夹的内容,但是dist文件夹是没有文件的,那么打包就没有意义了。
所以我们需要将也打包到dist文件夹中,这就需要使用**HtmlWebpackPlugin
**插件了。
HtmlWebpackPlugin
:
自动生成一个文件(指定模板)
将打包的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: ''
})
]
}
1.template表示根据哪个模板来生成
2.需要删除output中添加的publicPath属性,否则插入的script标签的src可能有误
再次打包,打开dist文件夹,多了一个
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: ''
}),
new uglifyjsWebpackPlugin()
]
}
打包过后,打开bundle.js,发现已经压缩了,此时版权声明被删除了。
webpack高版本自带了压缩插件。
webpack提供了一个可选的本地服务器, 这个本地服务器基于nodejs搭建, 内部使用express框架, 可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。
不过它是一个单独的模块,在webpack中使用之前需要先安装它
npm install --save-dev webpack-dev-server@2.9.1
devServe也是webpack中一个选项,选项本省可以设置一些属性:
修改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.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: ''
})
]
}
prod.config.js(构建发布时候需要的配置)
const uglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
plugins:[
new uglifyjsWebpackPlugin()
]
}
此时我们将webpack.config.js
文件分成了三个部分,公共部分、开发部分、构建发布的部分。
base.config.js
+dev.config.js
的内容base.config.js
+prod.config.js
的内容要将两个文件内容合并需要使用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
如对本文有疑问, 点击进行留言回复!!
offset、client、scroll (width,height、left,top、X,Y)
网友评论