模块化开发
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、查看版本
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 的某些包,执行 初始化
注意:在项目根目录下执行


再执行下面命令,安装一下依赖
webpack.config.js 添加内容
1 2 3 4 5 6 7 8 9 10
| const path = require('path')
module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, }
|
配置 完成后执行打包命令

但是这样还是很麻烦,如果你的文件改名,或者是多个文件,那就又变得很麻烦了,再做进一步简化
打开 生成的 package.json 文件,添加内容

script 下 添加 一个 build 脚本,当你执行 npm run 脚本名 的时候 它就会根据脚本名去执行对应的脚本内容
而且,执行时它会优先去找本地有没有这个命令
执行命令生成打包后的文件
在实际开发的时候,可能局部开发的环境和你安装全局环境不一样,这时候就需要安装一个局部环境,执行命令后会优先找局部
执行命令
注意:根目录下执行
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
| const path = require('path')
module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [ { test: /\.css$/, 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: 8192 } } ] } ] } }
|
normal.css 引入一张图片
1 2 3 4 5 6
| body {
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: 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 % }
安装
main.js 导入使用
1 2 3 4 5 6 7 8
| 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
| const vueLoaderPlugin = require('vue-loader/lib/plugin')
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
| 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"
|
跑起来
访问 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
| 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' }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.less$/, use: [{ loader: "style-loader" }, { loader: "css-loader" }, { loader: "less-loader" }] }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { 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' }
|
测试
1 2
| npm run build npm run dev
|