文章目录
- # 为什么需要模块化
- # 模块化?组件化?
- # 匿名函数的解决方案
- # 使用模块作为出口
- # CommonJS(了解)
- # ES6的export和import
- # 什么是Webpack?
- # 和 grunt/gulp 的对比
- # webpack 全局安装
- # 创建工程目录
- # js文件的打包
- # 使用打包后的文件
- # webpack配置
- # webpack核心:loader
- # less文件处理
- # 图片处理
- # 图片处理 - limit 分析
- # 图片处理 - 输出名字
- # 图片处理 - 总结
- # ES6语法处理
- # 引入 vue.js
- # 打包 vue 项目 – 错误信息
- # SPA 概念
- # el和template区别
- # 编写 `.vue` 文件
- # vue-loader
- # plugin的使用
- # 搭建本地服务器
- # 配置文件分离
- # 配置文件合并(分离后)
# 为什么需要模块化
回顾下 JavaScript
原始功能
在网页开发的早期, js
制作作为一种脚本语言,做一些简单的表单验证或动画实现等,<mark>那个时候代码还是很少的</mark>。
那个时候的代码是怎么写的呢?直接将代码写在 <script>
标签中即可
随着 ajax
异步请求的出现,<mark>慢慢形成了前后端的分离</mark>
客户端需要完成的事情越来越多,<mark>代码量也是与日俱增</mark>。
为了应对代码量的剧增,我们通常会将代码组织在多个 js
文件中,进行维护。
但是这种维护方式,依然不能避免一些灾难性的问题。
比如全局变量同名问题:(下图)
另外,这种代码的编写方式对 js
文件的依赖顺序几乎是强制性的
但是当 js
文件过多,比如有几十个的时候,弄清楚它们的顺序是一件比较同时的事情。
而且即使你弄清楚顺序了,也不能避免上面出现的这种尴尬问题的发生。
# 模块化?组件化?
- 《浅谈前端工程化、模块化、组件化》 - https://www.cnblogs.com/angel648/p/11370327.html
个人理解:<mark> APP⊂组件⊂模块</mark>
-
<mark>一个 APP 有多个组件</mark>(如:头部搜索栏、中间数据展示框、底层的选项框)
-
<mark>一个组件有多个模块</mark>(如:搜索栏有输入模块、搜索模块、缓存模块等。。。)
【两个组件之间的模块没关系,可以重复,可以不重复】
# 匿名函数的解决方案
以前,我们可以使用<mark>匿名函数来解决方面的重名问题</mark>
在aaa.js文件中,我们使用匿名函数
但,这会导致代码不可复用。
# 使用模块作为出口
作为成年人,<mark>变量重名的解决、代码复用</mark> 我全都要!!
name,就把闭包 return 出一个 变量导出
接下来,我们在main.js中怎么使用呢?
我们只需要使用属于自己模块的属性和方法即可
这就是模块最基础的封装,事实上模块的封装还有很多高级的话题:
但是我们这里就是要认识一下为什么需要模块,以及模块的原始雏形。
幸运的是,前端模块化开发已经有了很多既有的规范,以及对应的实现方案。
常见的模块化规范:
CommonJS、AMD、CMD,也有ES6的Modules
# CommonJS(了解)
模块化有两个核心:导出和导入
CommonJS
的导出:
CommonJS
的导入
# ES6的export和import
+《JS - 13 - 模块化》 - https://blog.csdn.net/LawssssCat/article/details/104463632
## export基本使用
export指令用于导出变量,比如下面的代码:
上面的代码还有另外一种写法:
## 导出函数或类
上面我们主要是输出变量,也可以输出函数或者输出类
上面的代码也可以写成这种形式:
## export default
某些情况下,一个模块中包含某个的功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名
这个时候就可以使用export default
我们来到main.js中,这样使用就可以了
这里的myFunc是我自己命名的,你可以根据需要命名它对应的名字
另外,需要注意:
export default在同一个模块中,不允许同时存在多个。
## import使用
我们使用export指令导出了模块对外提供的接口,下面我们就可以通过import命令来加载对应的这个模块了
首先,我们需要在HTML代码中引入两个js文件,并且类型需要设置为module
import指令用于导入模块中的内容,比如main.js的代码
如果我们希望某个模块中所有的信息都导入,一个个导入显然有些麻烦:
通过可以导入模块中所有的export变量
但是通常情况下我们需要给起一个别名,方便后续的使用
文章目录
- # 为什么需要模块化
- # 模块化?组件化?
- # 匿名函数的解决方案
- # 使用模块作为出口
- # CommonJS(了解)
- # ES6的export和import
- # 什么是Webpack?
- # 和 grunt/gulp 的对比
- # webpack 全局安装
- # 创建工程目录
- # js文件的打包
- # 使用打包后的文件
- # webpack配置
- # webpack核心:loader
- # less文件处理
- # 图片处理
- # 图片处理 - limit 分析
- # 图片处理 - 输出名字
- # 图片处理 - 总结
- # ES6语法处理
- # 引入 vue.js
- # 打包 vue 项目 – 错误信息
- # SPA 概念
- # el和template区别
- # 编写 `.vue` 文件
- # vue-loader
- # plugin的使用
- # 搭建本地服务器
- # 配置文件分离
- # 配置文件合并(分离后)
# 什么是Webpack?
<mark>前端、模块化、打包、工具</mark>
我们先看看官方的解释:
At its core, webpack is a static module bundler for modern JavaScript applications.
从本质上来讲,webpack是一个现代的<mark>JavaScript应用的静态模块打包工具</mark>。
我们从两个点来解释上面这句话:模块 和 打包
## 模块
模块概念前面说了。
就是 <mark>过程闭包、结果导出、使用导入</mark>
<mark>但是这样,又有一个问题,模块和模块之间相互依赖,需要管理工具。管理的手段就是“打包”</mark>
## 打包
就是将 webpack中各种模块进行合成一个包(Bundle)
<mark>在打包过程中,会对资源进行加工。
如:压缩图片、将scss转成css、将es6语法转成es5语法、将typeScript转成javaScript等</mark>
# 和 grunt/gulp 的对比
grunt/gulp 也是一个类似的工具。但是没有webpack强大。
下面左下对比
- 模块依赖简单、只需要进行简单的合并、压缩 ,那么,你可以使用 grunt/gulp
- 但是要对模块进行管理(模块之间依赖非常复杂了),那么需要用 webpack
- <mark>grunt/gulp 强调的是 前端流程的自动化,模块化不是核心</mark>
- <mark>webpack 强调模块化开发管理,前端自动(如文件压缩合并、预处理等)只是他的附带功能</mark>
# webpack 全局安装
官方教程:https://www.webpackjs.com/guides/installation/
安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm
查看自己的node版本: (要大于9)
node -v
全局安装webpack(这里我先指定版本号3.6.0,因为vue cli2依赖该版本)
<mark>官方不推荐全局安装,我们学习,怎么方便怎么来</mark>
npm install webpack@3.6.0 -g
<mark>这里,版本太高会依赖其他东西,你不会调的话,会报错哦</mark>
# 创建工程目录
准备工作
我们创建如下文件和文件夹:
文件和文件夹解析:
dist
文件夹(distribution):用于存放之后<mark>打包的文件</mark>src
文件夹:用于存放我们写的<mark>源文件</mark>main.js
:项目的<mark>入口文件</mark>。具体内容查看下面详情。mathUtils.js
:定义了一些数学<mark>工具函数</mark>,可以在其他地方引用,并且使用。具体内容查看下面的详情。
index.html
:浏览器打开展示的首页htmlpackage.json
:通过npm init生成的,npm包管理的文件(<mark>暂时没有用上,后面才会用上</mark>)
mathUtils.js
文件中的代码:
function add(num1, num2) {
return num1 + num2;
}
function mul(num1, num2) {
return num1 * num2;
}
module.exports = {
add,
mul
}
main.js
文件中的代码:
const {
add,
mul
} = require('./mathUtils.js');
console.log(add(20, 30))
console.log(mul(20, 30))
# js文件的打包
<mark>不可以直接使用我们前面写好的js</mark>
<mark>因为如果直接在index.html引入这两个js文件,浏览器并不识别其中的模块化代码。</mark>
<mark>且后期非常不方便对它们进行管理。</mark>
所以,我们需要用到webpack工具,对多个js文件进行打包。
来到 工程根目录,控制台输入命令
webpack .\src\main.js .\dist\bundle.js
工程目录 ./dist
下就 多了个打包好的文件
# 使用打包后的文件
打包后会在dist文件下,生成一个bundle.js文件
文件内容有些复杂,这里暂时先不看,后续再进行分析。
bundle.js文件,是webpack处理了项目直接文件依赖后生成的一个js文件,
<mark>我们只需要将这个js文件在index.html中引入即可</mark>
# webpack配置
我们希望通过配置,简化操作
## npm init -y
写webpack配置通常要用到 node 的环境
因此,下面生成 node 配置
npm init -y
## 入口和出口
官方教程:https://www.webpackjs.com/guides/getting-started/#使用一个配置文件
指定默认的 源码目录(.\src\main.js
),输出目录(.\dist\bundle.js
)
首先,创建一个 webpack.config.js
文件
const path = require('path')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
}
以后打包,只需要输入
webpack
就行了
## package.json中定义 script
但是,每次执行都敲这么一长串有没有觉得不方便呢?
OK,我们可以在package.json的scripts中定义自己的执行脚本。
## 局部安装webpack
目前,我们使用的webpack是全局的webpack,如果我们想使用局部来打包呢?
因为一个项目往往依赖特定的webpack版本,<mark>全局的版本可能很这个项目的webpack版本不一致,导出打包出现问题</mark>。
<mark>所以通常一个项目,都有自己局部的webpack</mark>。
第一步,项目中需要安装自己局部的webpack
这里我们让局部安装webpack3.6.0
npm install webpack@3.6.0 --save-dev
–save-dev
是开发时依赖,项目打包后不需要继续使用的。
Vue CLI3
中已经升级到webpack4
,但是它(webpack4
)将配置文件隐藏了起来,所以查看起来不是很方便。
看 package.json , 里面会多个 devDependencies
就是指定 开始时依赖的
再看目录,多了个 node_modules 目录,里面一堆依赖
前面两部的必要性
<mark>局部安装webpack 和 添加 build 指令。能让打包时候,webpack 从本地依赖当中优先打包(而不是从全局)</mark>
# webpack核心:loader
loader是webpack中一个非常核心的概念
<mark>需求:我们写好的东西,需要对其进行转换</mark>,转换成低版本浏览器也能使用的文件格式。(提高代码通用性)
如:我们需要加载css、图片,也包括一些高级的将 ES6 转换成 ES5 代码,将 TypeScript 转换成 ES5 代码,加你 scss、less 转成 css,将 .jsx
、.vue
文件转成 js 文件等等。
<mark>但是,webpack本身不支持此类的转换</mark>,需要我们给 webpack扩展loader
步骤
- 通过 npm 安装使用的 loader
- 在 webpack.config.js 中的 modules 关键下进行配置
大部分 loader 我们都可以在 webpack 的官方网站中找到 - 官网 loaders
## 案例:添加 css 样式的依赖
随便写一个样式
body{
background-color: red ;
}
去到官网 找 loaders
、、
看文字,可以领悟到,我们要同时使用 style-loader 和 css-loader
他的代码也这样写了
然后按照上面写的 ,先安装 loader
npm install style-loader --save-dev
npm install --save-dev css-loader
在入口文件引入 依赖
webpack.config.js 添加配置
,
module: {
rules: [{
test: /\.css$/,
// css-loader 只负责将css加载,不负责生效
// 如果要生效,还要安装 style-loader负责将样式添加到 DOM 中
// 使用多个 loader 时候,是从右向左
use: [{
loader: "style-loader"
},
{
loader: "css-loader"
}
]
}]
}
编译 (之前配置了,所以可以这样写,如果不行,看上章配置)
npm run build
done
# less文件处理
随便写个 less 文件
@fontSize: 50px;
@fontColor: orange;
body {
font-size: @fontSize;
color: @fontColor;
}
main.js 中添加 依赖
// 依赖less文件
require('./css/special.less');
document.writeln(`<h2>你好啊!</h2>`)
查官网资料:https://www.webpackjs.com/loaders/less-loader/
知道安装 :
npm install --save-dev less-loader less
并且在 webpack.config.js中添加 rules
// webpack.config.js
module.exports = {
...
module: {
rules: [{
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
}]
}]
}
};
编译 (之前配置了,所以可以这样写,如果不行,看上章配置)
npm run build
done
# 图片处理
修改 css样式,引用图片资源
body {
/* background-color: red ; */
background: url('../img/spring.jpg');
}
编译时候,会报错
添加 rules
<mark>注意:这里要改limit,大于你请求的图片大小, 如:10kb就写10240以上</mark>
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
再次编译
done
# 图片处理 - limit 分析
当加载图片,小于 limit 时,会将图片编译成 base64字符串形式
而当 大于 limit 时,会用 file-loader 处理。(你可以试下:换张大图,再次编译,会出现以下错误)
原因是你没有安装file loader(那安装呗)
安装编译后,<mark>发现仍然没有显示</mark>
并且控制台报错
控制台说的 是图片找不到
看body上的 url 引用,引用的是 index.html 即 src目录下的 图片。
而我们图片生成在了 /dist 目录下,我们把图片拷贝到根目录,
图片找到了,
但每次手动更改显然不可行,怎么办?
只需要在 webpack 配置里面 的 output 里面 加一个属性
看官方文档
- output.publicpath https://www.webpackjs.com/configuration/output/#output-publicpath
这里的publicpath
可以理解为是 <mark>修改整个项目名</mark>
# 图片处理 - 输出名字
图片找到了,但是,如果一堆乱七八糟名字的图片放在 dist目录下,也很头疼
这是需要在 options 里面再添加一个属性 name
(如下)
name: 'img/[name].[hash:8].[ext]'
name 图片原来的名字
hash 根据图片信息算出来了hash值(冲突概率极小)
hash:8 截取hash值前8位
ext 图片原有后缀
结果
# 图片处理 - 总结
- 当加载的图片,小于limit时,会将图片编译成base64字符串形式
- 当加载的图片,大于limit时,需要使用file-loader模块进行加载(这时候需要配置 output.publicPath)
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'dist/',
},
同时, 如果想定制图片转换后的目录和名字,需要这样配置(下图) - 官方的相关文档
}]
}, {
test: /\.(png|jpg|gif|jpeg)$/,
use: [{
loader: 'url-loader',
options: {
// 当加载的图片,小于limit时,会将图片编译成base64字符串形式
// 当加载的图片,大于limit时,需要使用file-loader模块进行加载(这时候需要配置 output.publicPath)
limit: 8192,
name: 'img/[name].[hash:8].[ext]'
}
}]
}]
}
# ES6语法处理
如果你仔细阅读webpack打包的js文件,<mark>发现写的ES6语法并没有转成ES5</mark>,那么就意味着可能一些对ES6还不支持的浏览器没有办法很好的运行我们的代码。
这里不用脚手架
看官网怎么做
下面,就用 babel
为例子,实现转换。
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
# 引入 vue.js
后续项目中,我们会使用Vuejs进行开发,而且会以特殊的文件来组织vue的组件。
所以,<mark>下面我们来学习一下如何在我们的webpack环境中集成Vuejs</mark>
现在,我们希望在项目中使用Vuejs,那么必然需要对其有依赖,所以需要先进行安装
npm install --save vue
注:<mark>因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖</mark> ,而是用 --save
那么,接下来就可以按照我们之前学习的方式来使用 Vue
了
main中添加
// 引入 vue 模块
import Vue from 'vue' ;
const app = new Vue({
el: '#app' ,
data: {
message: '你好啊!'
}
})
index 中添加
<body>
<div id='app'>
<h2>{{message}}</h2>
</div>
<script src="./dist/bundle.js"></script>
</body>
# 打包 vue 项目 – 错误信息
修改完成后,重新打包,运行程序:
打包过程没有任何错误(因为只是多打包了一个vue的js文件而已)
但是运行程序,没有出现想要的效果,而且浏览器中有报错
You are using the runtime-only build of Vue where the template compiler is not available.
Either pre-compile the templates into render functions, or use the compiler-included build.
你正在用 Vue 的 runtime-only 版本编译,这个版本对 template 是不可用的。
你要么把 template 放进预编译函数,要么使用 complier-included 版本编译。
这个错误说的是我们使用的是runtime-only版本的Vue,什么意思呢?
这里我只说解决方案:Vue不同版本构建,后续我具体讲解runtime-only和runtime-compiler的区别。
vue 官方给出的 解决方案 《运行时 + 编译器 vs. 只包含运行时》
所以我们修改webpack的配置,添加如下内容即可
module.exports = {
.......
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // 用 webpack 1 时需用 'vue/dist/vue.common.js'
}
}
}
# SPA 概念
我们现在 主要开发
SPA
(simple page web application
) 单页面 Web 应用 - 详细介绍
那如果后期有多个页面怎么办?
.
我们会用到路由技术
.
vue-router
(前端路由)(后期讲到,现在不管)
# el和template区别
正常运行之后,我们来考虑另外一个问题:
- 如果我们希望将
data
中的数据显示在界面中,就必须是修改index.html
- 如果我们后面自定义了组件,也必须修改index.html来使用组件
- 但是
html
<mark>模板在之后的开发中,我并不希望手动的来频繁修改</mark>,是否可以做到呢?
# 编写 .vue
文件
定义 template
属性:
-
在前面的
Vue
实例中,我们定义了el
属性,用于和index.html
中的#app
进行绑定,让Vue
实例之后可以管理它其中的内容 -
这里,我们可以将
div元素
中的{{message}}
内容删掉,只保留一个基本的id
为div
的元素
-
但是如果我依然希望在其中显示
{{message}}
的内容,应该怎么处理呢? -
我们可以写一个
.vue
文档,并且把组件的代码放在其里面,代码如下:
App.vue<template> <div> <h2 class="title">{{ message }}</h2> <button @click="btnClick">按钮</button> <h2>{{ name }}</h2> </div> </template> <script> export default { name: "App", // 组件的标签名字(在 vue dev-tool 中可以看到) data() { return { message: "** 你老*!", name: "梁非凡!!!" }; }, methods: { btnClick() { alert("btnClick"); } } }; </script> <style> .title { color: green; } </style>
main.js
// 引入 vue 模块 import Vue from 'vue'; import App from './vue/App.vue' new Vue({ el: '#app', template: `<App/>`, components: { App } })
# vue-loader
上面代码写好后,我们编译报错(下图),原因很简单,没有 .vue
后缀的 loader 。(那就安装呗)
查看文档 - Vue Loader
运行下面指令安装
npm install -D vue-loader vue-template-compiler
–save-dev=-D,安装的包将写入packege.json里面的devDependencies,devdependencies:只有开发环境下需要依赖的库
配置里面添加
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
module: {
rules: [
// ... 其它规则
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin()
]
}
<mark>以上弄好,编译</mark>
坑
这里如果编译出现异常
VueLoaderPlugin is not defined
参考这篇文档
vue-loader@15.x VueLoaderPlugin 踩坑// 打开webpack的配置文件 webpack.config.js: const { VueLoaderPlugin } = require('vue-loader');
done!
文章目录
- # 为什么需要模块化
- # 模块化?组件化?
- # 匿名函数的解决方案
- # 使用模块作为出口
- # CommonJS(了解)
- # ES6的export和import
- # 什么是Webpack?
- # 和 grunt/gulp 的对比
- # webpack 全局安装
- # 创建工程目录
- # js文件的打包
- # 使用打包后的文件
- # webpack配置
- # webpack核心:loader
- # less文件处理
- # 图片处理
- # 图片处理 - limit 分析
- # 图片处理 - 输出名字
- # 图片处理 - 总结
- # ES6语法处理
- # 引入 vue.js
- # 打包 vue 项目 – 错误信息
- # SPA 概念
- # el和template区别
- # 编写 `.vue` 文件
- # vue-loader
- # plugin的使用
- # 搭建本地服务器
- # 配置文件分离
- # 配置文件合并(分离后)
# plugin的使用
webpack
中的插件,就是对 webpack
<mark>现有功能的各种扩展</mark>,比如打包优化,文件压缩等等。
loader和plugin区别
- loader主要用于转换某些类型的模块,它是一个 <mark>转换器</mark>。
- plugin是插件,它是对webpack本身的扩展,是一个 <mark>扩展器</mark>。
plugin的使用过程:
- 步骤一:通过
npm
安装需要使用的plugins
(某些webpack已经内置的插件不需要安装) - 步骤二:在
webpack.config.js
中的plugins
中配置插件。
下面,我们就来看看可以通过哪些插件对现有的webpack打包过程进行扩容,让我们的webpack变得更加好用。
## 添加版权的 Plugin
我们先来使用一个最简单的插件,<mark>为打包的文件添加版权声明</mark> (如下)
(了解:MIT是一个比较开放的协议)
该插件名字叫 BannerPlugin
,属于 webpack
自带的插件。 - – - - 官方介绍
按照下面的方式来修改 webpack.config.js
的文件:
const webpack = require('webpack');
....
plugins: [
new webpack.BannerPlugin({
banner: "hash:[hash], chunkhash:[chunkhash], name:[name], filebase:[filebase], query:[query], file:[file]"
})
]
重新打包程序:查看 bundle.js
文件的头部,看到如下信息
## 打包html的plugin
目前,我们的
index.html
文件是存放在项目的根目录下的。
但在真实发布项目时,发布的是dist
文件夹中的内容,我们应该吧index.html
也放在dist
里面(同时保证依赖不乱)
<mark>HtmlWebpackPlugin
插件可以为我们做这些事情:</mark>
- 自动生成一个index.html文件(可以指定模板来生成)
- 将打包的js文件,自动通过script标签插入到body中
安装 HtmlWebpackPlugin
插件: api
npm install --save-dev html-webpack-plugin
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
var webpackConfig = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js' ,
// publicPath: 'dist/', 这个注释掉 // 以后可以作为项目路径
},
plugins: [new HtmlWebpackPlugin({
template: 'index.html' // 指定模板
})
]
};
关于 这个插件的其他配置 参考 - 官方文档
done!
## js 压缩插件
API - https://www.webpackjs.com/plugins/uglifyjs-webpack-plugin/
npm i -D uglifyjs-webpack-plugin
错误:
Cannot read property 'compilation' of undefined
把版本改低,然后npm install
done
# 搭建本地服务器
webpack
提供了一个可选的本地开发服务器,这个本地服务器基于 node.js
搭建,内部使用 express
框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。
不过它是一个单独的模块,在 webpack
中使用之前需要先安装它 - 官方API文档
npm install --save-dev webpack-dev-server
修改 webpack.config.js
devServer: {
contentBase: './dist',
inline: true
},
其中:
还可以设置其他选项
contentBase
:为哪个文件夹提供本地服务,默认是根文件夹,我们这里需要填写./dist
port
:端口号
inline
: 页面实时刷新
historyApiFallback
: 在 SPA 页面中,依赖HTML5的history模式(<mark>后面路由时候讲</mark>)
让我们添加一个 script 脚本,可以直接运行开发服务器(dev server):
package.json
"start": "webpack-dev-server --open",
--open
自动打开
现在,我们可以在命令行中运行 npm start
or npm run start
,就会看到浏览器自动加载页面。如果现在修改和保存任意源文件,web 服务器就会自动重新加载编译后的代码。试一下!
关于 Server 的更多
如果报错:
Error: Cannot find module 'webpack-cli/bin/config-yargs'
那是我们没有安装脚手架
然后你的版本太高了
我们把版本降到 2.9.3(webpac3.6.0)
done
除此之外,vscode的插件
LiveServer
也可以实现这功能,一键安装不用配置,适合新手玩。try it~
# 配置文件分离
配置很多,有的生产环境不需要,有的开发环境不需要
我们需要把配置文件分离(为脚手架
打基础)
创建新文件夹 build
分成三个文件 , 把 webpack.config.js
的所有配置进行拆分
- base 公共
- dev 开发
- prod 生产
base.config.js(下)
const path = require('path')
const {
VueLoaderPlugin
} = require('vue-loader');
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: [{
loader: "style-loader"
},
{
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|jpeg)$/,
use: [{
loader: 'url-loader',
options: {
// 当加载的图片,小于limit时,会将图片编译成base64字符串形式
// 当加载的图片,大于limit时,需要使用file-loader模块进行加载(这时候需要配置 output.publicPath)
limit: 8192,
name: 'img/[name].[hash:8].[ext]'
}
}]
}, {
test: /\.js$/,
// 排除 node_modules 里面的 js
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
// presets: ['@babel/preset-env']
presets: ['es2015']
}
}
}, {
test: /\.vue$/,
loader: 'vue-loader'
}]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // 用 webpack 1 时需用 'vue/dist/vue.common.js'
}
},
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin(),
new webpack.BannerPlugin({
banner: "hash:[hash], chunkhash:[chunkhash], name:[name], filebase:[filebase], query:[query], file:[file]"
}),
new HtmlWebpackPlugin({
template: 'index.html'
}),
]
}
prod.config.js(下:生产环境)
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin');
const webpackMerge = require('webpack-merge'); // 新添加的,用于合并
const baseConfig = require('./base.config') // 新添加的,用于合并
module.exports = webpackMerge(baseConfig, {
plugins: [
// 开发阶段不需要丑化
new UglifyWebpackPlugin()
]
})
dev.config.js(下:开发环境)
const webpackMerge = require('webpack-merge');// 新添加的,用于合并
const baseConfig = require('./base.config')// 新添加的,用于合并
module.exports = webpackMerge(baseConfig, {
devServer: {
contentBase: './dist',
inline: true
}
})
# 配置文件合并(分离后)
安装
npm i -D webpack-merge
修改 package.json,指定新配置的位置
"build": "webpack --config ./build/prod.config.js",
"start": "webpack-dev-server --open --config ./build/dev.config"
- build 用于发布
- start 用于开发
最后修改 base.config.js
里面 output 指定的输出地址
最后 build 和 start 看效果吧
done
文章目录
- # 为什么需要模块化
- # 模块化?组件化?
- # 匿名函数的解决方案
- # 使用模块作为出口
- # CommonJS(了解)
- # ES6的export和import
- # 什么是Webpack?
- # 和 grunt/gulp 的对比
- # webpack 全局安装
- # 创建工程目录
- # js文件的打包
- # 使用打包后的文件
- # webpack配置
- # webpack核心:loader
- # less文件处理
- # 图片处理
- # 图片处理 - limit 分析
- # 图片处理 - 输出名字
- # 图片处理 - 总结
- # ES6语法处理
- # 引入 vue.js
- # 打包 vue 项目 – 错误信息
- # SPA 概念
- # el和template区别
- # 编写 `.vue` 文件
- # vue-loader
- # plugin的使用
- # 搭建本地服务器
- # 配置文件分离
- # 配置文件合并(分离后)