avatar

Vue-3-模块化开发-webpack

模块化开发

JavaScript原生功能

ES6模块化的实现

引入文件时 加上 type=“module” 属性 标识模块化

这样各个文件的内容都是互相隔离的,那要如何访问其他文件的属性?

使用 export

export

导出方式1:

在js文件中 定义 export

在其他的 js 文件中就可以引用了

浏览器显示

导出方式2:

其他文件引用

导出函数或类

使用

export default

  • 草此情况下,一个模块中包含某个的功能,我们并不希望给这个功能命名,而日让导入 者可以自己来命名

import

简单的使用上面已经讲述

1
2
// 统一全部导入
import * as 别名 from './aaa.js'

Webpack详解

什么是Webpack?

官方:

At its core, webpack is a static module bundler for modern JavaScript applications.
从本质上来讲, webpack是一个现代的JavpScript应用的静态模块打包工具。

前端模块化

webpack的安装

webpack 依赖于 node.js node.js自带软件管理工具 npm

1、官网下载 安装 node.js

https://nodejs.org/en/

2、cmd中使用 npm 全局安装 webpack,和webpack-cli

1
2
npm install webpack@4.42.1 -g
npm install webpack-cli -g

3、查看版本

1
2
node -v
webpack-cli -v

webpack的起步

新建文件夹 dist、src

dist:打包目录

src:源代码目录


src下创建俩文件

main.js

1
2
3
4
const {add,mul} = require('./mathUtils.js')

console.log(add(20, 30));
console.log(mul(20, 30));

mathUtils.js

1
2
3
4
5
6
7
8
9
10
11
function add(num1, num2) {
return num1 + num2
}

function mul(num1, num2) {
return num1 * num2
}

module.exports = {
add,mul
}

src 同级 目录下创建 index.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

</body>
</html>

创建完后我们发现,编写的代码不容易测试,这个时候我们就需要打包

打包命令

注意:根据自己的文件地址修改下面的命令

1
webpack ./src/main.js --output-filename bundle.js --output-pth (./dist) --mode development
  • ./src/main.js 为需要打包得文件路径
  • bundle.js 为打包后得文件名
  • (./dist) 为打包后放在哪儿

打包时可能会出现 webpack未安装 得提示,运行下面得命令,再打包

注意:在项目根目录下执行

1
npm install --save-dev webpack

访问index 页面

webpack的配置

每次修改文件后都需要打包一次,那么长一串 命令属实头大,下面通过配置来简化

创建 webpack.config.js 配置文件

需要用到 node.js 的某些包,执行 初始化

注意:在项目根目录下执行

1
npm init

再执行下面命令,安装一下依赖

1
npm install

webpack.config.js 添加内容

1
2
3
4
5
6
7
8
9
10
// 依赖于node包,要使用 npm init 创建 package.json
const path = require('path')

module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
}
  • entry:入口,写上你要打包文件的路径

  • output:出口

  • __dirname:node 里自带的全局变量,当前 webpack.config.js 文件所在的路径

    dirname 前面是 两个 _ 下划线

  • path:绝对路径

配置 完成后执行打包命令

1
webpack

但是这样还是很麻烦,如果你的文件改名,或者是多个文件,那就又变得很麻烦了,再做进一步简化

打开 生成的 package.json 文件,添加内容

script 下 添加 一个 build 脚本,当你执行 npm run 脚本名 的时候 它就会根据脚本名去执行对应的脚本内容

而且,执行时它会优先去找本地有没有这个命令

执行命令生成打包后的文件

1
npm run build

在实际开发的时候,可能局部开发的环境和你安装全局环境不一样,这时候就需要安装一个局部环境,执行命令后会优先找局部

执行命令

注意:根目录下执行

1
npm install webpack@4.42.1 --save-dev

loader

什么是loader

中文文档 https://www.webpackjs.com/loaders/css-loader/

css文件处理

执行命令

1
2
npm install --save-dev css-loader
npm install style-loader --save-dev

webpack.config.js 添加内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 依赖于node包,要使用 npm init 创建 package.json
const path = require('path')

module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
// css-loader 只负责将css文件进行加载
// style-loader 负责将样式添加到DOM中
// 使用多个loader时,是从右到左
use: [ 'style-loader','css-loader' ]
}
]
}
}

{ % note warning% }

style-loader:负责解析样式

css-loader:负责加载文件

{ %endnote% }

index.html 引入 css 文件

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

<link href="./src/css/normal.css">
</head>
<body>
<script src="./dist/bundle.js"></script>
</body>
</html>

效果就有了

less文件处理

和 css 文件处理一样,文档中找到对应的依赖安装

中文文档https://www.webpackjs.com/loaders/less-loader/

图片文件处理

url-loader

执行命令

1
npm install --save-dev url-loader

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 当加载的图片,小于limit时,会将图片编译成base64字符串形式
// 当加载的图片,大于limit时,需要使用file-loader模块进行加载
limit: 8192
}
}
]
}
]
}
}

normal.css 引入一张图片

1
2
3
4
5
6
body {
/*background-color: blue;
color: red;*/

background: url("../img/1060624.png");
}

正常显示

图片是一个base64格式

什么是base64?https://blog.csdn.net/qq_20545367/article/details/79538530

当你的图片大小大于所设 limit: 时,需要 file-loader来处理

file-loader

执行命令

1
npm install --save-dev file-loader

打包,查看

我们发现图片显示不出来

因为 当图片大于所设 limit 时,程序会使用 file-loader 进行处理,而处理后会打包生成一个以36位hash命名的图片副本 打包到打包目录

此时浏览器访问的却是 根目录下的 图片,所以我们要指定一个路径

webpack.config.js 添加

再打包访问,成功

修改 file-loader 默认图片名字

file-loader 自动生成的图片名字太长,不清晰,我们可以自定义名字格式

webpack.config.js 添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 当加载的图片,小于limit时,会将图片编译成base64字符串形式
// 当加载的图片,大于limit时,需要使用file-loader模块进行加载
limit: 50,
name: 'img/[name].[hash:8].[ext]'
}
}
]
}
]
}

ES6语法处理

有些浏览器可能不支持ES6语法,需要进行处理

安装 babel-loader

1
npm install babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env webpack

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}

重新构建

webpack配置vue

引入vue.js 有三种方式

  • 直接下载 vue.js 文件引入
  • CDN引入
  • npm 安装

{ % noteinfo % }

遵循模块化开发规范,使用 npm 安装局部 vue

{ % endnote % }

安装

1
npm install vue --save

main.js 导入使用

1
2
3
4
5
6
7
8
// 5、使用vue进行开发
import Vue from 'vue'
const app = new Vue({
el: '#app',
data: {
message: 'Hello Webpack'
}
})

webpack.config.js 更改配置

  • 默认使用的vue版本是 runtime-only,需要更改

和module同级

1
2
3
4
5
6
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}

}

浏览器就有显示了

el和template区别

main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import Vue from 'vue'
const app = new Vue({
el: '#app',
template: `
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按钮</button>
<h2>{{name}}</h2>
</div>
`,
data: {
message: 'Hello Webpack',
name: 'coderwhy'
},
methods: {
btnClick(){

}
}
})

浏览器查看

template 会把 el挂载的实例里的东西替换

但是这样还是不好,因为 js 代码和 模板混合到了一起,下面就将这些进行进一步封装

Vue终极使用方案

安装

1
npm install --save-dev vue-loader vue-template-compiler

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//文件头上引入插件不然用不了 vue-loader
const vueLoaderPlugin = require('vue-loader/lib/plugin')

//注意这个要放在 module.exports 里面
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
],
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
plugins: [
new vueLoaderPlugin()
]
}

创建 App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<template>
<div>
<h2 class="title">{{message}}</h2>
<button @click="btnClick">按钮</button>
<h2>{{name}}</h2>
</div>
</template>

<script>
export default {
name: "App",
data() {
return {
message: 'Hello Webpack',
name: 'coderwhy'
}
},
methods: {
btnClick(){

}
}
}
</script>

<style scoped>
.title {
color: green;
}
</style>

main.js

1
2
3
4
5
6
7
8
9
10
11
// 5、使用vue进行开发
import Vue from 'vue'
import App from './vue/App.vue'

new Vue({
el: '#app',
template: `<App/>`,
components: {
App
}
})

执行构建命令成功构建.

组件中还可以注册组件

创建 Cpn.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div>
<h2>我是cpn组件</h2>
<p>我是cpn组件的内容</p>
</div>
</template>

<script>
export default {
name: "Cpn",
data(){
return {
name: 'Cpn组件的name'
}
}
}
</script>

<style scoped>

</style>

App.vue中注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<template>
<div>
<h2 class="title">{{message}}</h2>
<button @click="btnClick">按钮</button>
<h2>{{name}}</h2>
<Cpn></Cpn>
</div>
</template>
<script>
import Cpn from './Cpn.vue'

export default {
name: "App",
components: {
Cpn
},
data() {
return {
message: 'Hello Webpack',
name: 'coderwhy'
}
},
methods: {
btnClick() {

}
}
}
</script>
<style scoped>
.title {
color: green;
}
</style>

效果:

认识plugin

webpack 横幅Plugin的使用

添加版权的Plugin

  • 我们先来使用一个最简单的插件,为打包的文件添加版权声明
    • 该插件名字叫BannerPlugin ,属于webpack自带的插件。

webpack.config.js

1
2
3
4
5
6
7
8
const webpack = require('webpack')

module.exports = {
plugins: [
new vueLoaderPlugin(),
new webpack.BannerPlugin('最终版权归独秀所有')
]
}

重新构建,查看效果

打包html的plugin

安装

1
2
3
npm install html-webpack-plugin --save-dev
// 或者
npm install html-webpack-plugin@3.2.0 --save-dev

将原来的 index.html 的 script 引入删除

修改 webpack.config.js

重新构建查看

js压缩的plugin

安装

1
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

重新构建查看

当前webpack 4及以上版本 在打包的时候会自动进行压缩,所以高版本不用在多去配置

搭建本地服务器

每次改一下代码都得重新打包,非常繁琐,如果代码量大了之后打包的速度可能会非常慢,可以搭建一个本地服务器解决这种问题

安装

1
npm install webpack-dev-server --save-dev

webpack.config.js

1
2
3
4
5
6
7
8
module.exports = {
devServer: {
// 服务与哪个文件夹
contentBase: './dist',
// 是否实时监听
inline: true
}
}

package.json 的 scripts 中配置

1
2
3
4
"dev": "webpack-dev-server"

// 启动后自动打开网页
"dev": "webpack-dev-server --open"

跑起来

1
npm run dev

访问 http://localhost:8080/

实时监控更新,代码更改后能快速更新

本地服务器的内容是存储在内存中的,所以该打包还是得打包

分离 webpack.config.js 文件

将开发和发布的配置分离

创建 build 文件夹,再创建三个js文件

  • base.config.js 公共
  • dev.config.js 开发
  • prod.config.js 发布

安装插件 将 三个文件能够互相组合

1
npm install webpack-merge --save-dev

base.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// 依赖于node包,要使用 npm init 创建 package.json
const path = require('path')
const vueLoaderPlugin = require('vue-loader/lib/plugin')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
// publicPath: 'dist/'
},
module: {
rules: [
{
test: /\.css$/,
// css-loader 只负责将css文件进行加载
// style-loader 负责将样式添加到DOM中
// 使用多个loader时,是从右到左
use: ['style-loader', 'css-loader']
},
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 当加载的图片,小于limit时,会将图片编译成base64字符串形式,
// 当加载的图片,大于limit时,需要使用file-loader模块进行加载,
limit: 50,
name: 'img/[name].[hash:8].[ext]'
}
}
]
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
plugins: [
new vueLoaderPlugin(),
new webpack.BannerPlugin('最终版权归独秀所有'),
new HtmlWebpackPlugin({
template: 'index.html'
})
]
}

dev.config.js

1
2
3
4
5
6
7
8
9
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin')
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')

module.exports = webpackMerge(baseConfig, {
plugins: [
new UglifyWebpackPlugin()
]
})

prod.config.js

1
2
3
4
5
6
7
8
9
10
11
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')

module.exports = webpackMerge(baseConfig, {
devServer: {
// 服务与哪个文件夹
contentBase: './dist',
// 是否实时监听
inline: true
}
})

webpack.config.js 就可以删了 (建议先弄出来备份一下再删)

修改package.json文件 的 scripts

1
2
"build": "webpack --config ./build/prod.config.js",
"dev": "webpack-dev-server --config ./build/dev.config.js"

修改 base.config.js

1
2
3
4
5
6
output: {
// 修改打包路径
path: path.resolve(__dirname, '../dist'),
filename: 'bundle.js'
// publicPath: 'dist/'
}

测试

1
2
npm run build
npm run dev
文章作者:
文章链接: https://huohuohuohuohuohuo.github.io/2020/04/16/Vue-3-模块化开发-webpack/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论