1. 什么是Webpack
1.1 引入
1.2 模块化
1.3 打包
1.4 Webpack和grunt/gulp对比
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.task('js',() =>
gulp.src('src/*.js')
.pipe(babel)({
presets: ['es 2015']
})
.pipe(gulp.dest('dist'))
);
2. Webpack安装
node -v
npm install webpack@3.6.0 -g
cd 对应目录
npm install webpack@3.6.0 --save-dev
- 在终端直接执行
webpack命令
,使用的全局安装的webpack
- 当在
package.json
中定义了scripts时,其中包含了webpack命令
,那么使用的是局部webpack
3. 使用Webpack
3.1 准备环境
function add(num1,num2) {
return num1 + num2;
}
function mul(num1,num2) {
return num1 * num2;
}
module.exports = {
add,mul
}
//ES6的模块化规范
export let name = 'rose';
export let age = 18;
export let gender = '男';
//CommonJS的模块化规范
const math = require('./CommonJS');
//ES6的模块化规范
import * as person from './ES6';
console.log('Hello Webpack');
console.log(math.add(10,20));
console.log(math.mul(10,20));
console.log(person.name);
console.log(person.age);
console.log(person.gender);
- 我们知道,webpack就是一个模块化的打包工具,所以它支持我们代码中写模块化,可以对模块化的代码进行处理。(如何处理的待会儿在原理中,我会讲解)
- 另外,如果在处理完所有模块之间的关系后,将多个js打包到一个js文件中,引入时就变得非常方便了。OK,如何打包呢?使用webpack的指令即可
webpack ./src/main.js ./dist/bundle.js
- 文件内容有些复杂,这里暂时先不看,后续再进行分析。
-
bundle.js
文件是webpack处理了项目直接文件依赖后生成的一个js文件,我们只需要将这个js文件在index.html
中引入即可。
<script src="./dist/bundle.js"></script>
3.2 Webpack配置
//node的语法:导入path包,该path不用我们自己写而是去node的包里找的(在这之前注意使用npm init命令初始化生成package.json文件)
const path = require('path');
module.exports = {
//入口:可以是字符串/数组/对象,这里我们入口只有一个所以写一个字符串即可
entry: 'src/main.js',//出口:通常是一个对象,里面至少包含两个重要属性,path 和 filename
output: {
//注意:path要写绝对路径(为了防止结构改变,且要动态的获取绝对路径)
//path.resolve()函数:对两个参数进行拼接
//__dirname:node上下文中的全局变量,保存的就是当前文件所在的绝对路径
path: path.resolve(__dirname,'dist'),//打包之后生成文件的名字
filename: 'bundle.js'
}
}
- 第一步,项目中需要安装自己局部的webpack。这里我们让局部安装
webpack3.6.0
,Vue CLI3
中已经升级到 webpack4
,但是它将配置文件隐藏了起来,所以查看起来不是很方便。
npm install webpack@3.6.0 --save-dev
- 第二步,通过
node_modules\.bin\webpack
启动webpack打包
- 首先,会寻找本地的node_modules/.bin路径中对应的位置
- 如果没有找到,会去全局的环境变量中寻找
- 如何执行我们的build指令呢? =>
npm run build
3.3 CSS文件处理
- 在我们之前的实例中,我们主要是用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖。
- 但是在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成JavaScript代码,将scss、less转成css,将.jsx、.vue文件转成js文件等。
- 对于webpack本身的能力来说这些转化是不支持的那怎么办呢?给webpack扩展对应的loader就可以啦。
- 在src目录中创建一个css文件,其中创建一个
normal.css
文件。
- 我们也可以重新组织文件的目录结构,将零散的js文件放在一个js文件夹中。
module: {
rules: [
{
// 匹配.css结尾的
test: /\.css$/,//css-loader只负责将css文件进行加载
//style-loader负责将样式添加到DOM中
use: [ 'style-loader','css-loader' ]
}
]
}
3.4 Less文件处理
//注意,可能会出现less-loader版本过高的情况,请适当降低版本
npm install --save-dev less-loader@5.0.0 less
- 其次修改对应的配置文件。添加一个rules选项,用于处理
.less
文件
3.5 图片文件处理
body {
background-color: skyblue;
background: url(../imgs/test01.png);
}
npm install --save-dev url-loader
//注意:版本过高会报错
npm install --save-dev file-loader@5.5.0
- img:文件要打包到的文件夹
- name:获取图片原来的名字,放在该位置
- hash:8:为了防止图片名称冲突,依然使用hash,但是我们只保留8位
- ext:使用图片原来的扩展名
{
test: /\.(png|jpg|gif)$/,use: [
{
loader: 'url-loader',options: {
limit: 8192,//[]里写变量,ext代表扩展名
name: 'image/[name]_[hash:8].[ext]'
}
}
]
},
3.6 ES6语法处理
//1. 我们安装了 7版本的babel-loader,babel-core,babel-preset-es2015
//2.官网是babel-preset-env而不是babel-preset-es2015,如果是babel-preset-env的话我们还需要对它进
// 行配置。这里我们只使用了ES6的语法就先简单用一下babel-preset-es2015即可,后面再了解babel-preset-
// env的配置
npm install babel-loader@7.0.0 babel-core babel-preset-es2015
{
test: /\.js$/,//排除node_modules这个文件
exclude: /(node_modules|bower_components)/,use: {
loader: 'babel-loader',options: {
presets: ['es2015']
}
}
}
4. Webpack配置Vue
4.1 引入vue.js
npm install vue@2.6.0 --save
resolve: {
//alias: 别名
alias: {
//当我们通过 import Vue from vue 导入vue时,会去找我们配置的指定vue版本
//默认找的是vue.runtime.js
'vue$': 'vue/dist/vue.esm.js'
}
}
4.2 el和template的区别
import Vue from 'vue';
new Vue({
el: '#app',template: `
<div id="app">
<h2>{{name}}</h2>
</div>`,data: {
name: 'polaris'
}
})
4.3 Vue组件化开发引入
import Vue from 'vue';
const App = {
template: '<h2>{{name}}</h2>',data(){
return {
name: 'polaris'
}
}
}
new Vue({
el: '#app',template:
`<div id="app">
<App/>
</div>`,components: {
App
}
})
export default {
template: '<h2>{{name}}</h2>',data(){
return {
name: 'polaris'
}
}
}
import Vue from 'vue';
import App from './vue/app.js';
new Vue({
el: '#app',components: {
App
}
})
4.4 .vue文件封装处理
<template>
<div>
<h2>{{name}}</h2>
</div>
</template>
<script>
export default {
data(){
return {
name: 'polaris'
}
}
}
</script>
<style scoped>
h2 {
color: blueviolet;
}
</style>
import Vue from 'vue';
// import App from './vue/app.js';
import App from './vue/App.vue';
new Vue({
el: '#app',components: {
App
}
})
//vue-loader的版本在14+之后还需要配置一个插件
//vue-template-compiler的版本与vue版本对应即可
npm install vue-loader@13.0.0 vue-template-compiler@2.6.0 --save-dev
//注意:如果写了css,less等,记得还要加上对应的loader
{
test: /\.vue$/,use: ['vue-loader']
}
4.5 实现导入.vue文件时不加后缀
//webpack中resolve主要是解决一些路径相关的问题
resolve: {
extensions:['.js','.css','.vue']
}
5. plugin的使用
5.1 认识plugin
5.2 添加版权的Plugin
const webpack = require('webpack');
module.exprots = {
...
plugins: [
new webpack.BannerPlugin('最终版权归polaris所有')
]
}
5.3 打包html的Plugin
//报错就换一下版本
npm install html-webpack-plugin@3.2.0 --save-dev
const htmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new htmlWebpackPlugin({
//template表示根据什么模板来生成index.html
//如下配置会在当前webpack配置文件所在目录下找index.html作为模板
template: 'index.html'
}),]
5.4 js压缩的Plugin
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
const uglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exprots = {
...
plugins: [
new uglifyJsPlugin()
]
}
6. 本地服务器
6.1 搭建本地服务器
//vue cli2 => webpack@3.6.0 => webpack-dev-server@2.9.1
npm install webpack-dev-server@2.9.1 --save-dev
-
contentBase
:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist
-
port
:端口号,默认8080
-
inline
:页面实时刷新
-
historyApiFallback
:在SPA页面中,依赖HTML5的history模式
devServer: {
contentBase: './dist',inline: true
}
"dev":"webpack-dev-server --open"
6.2 webpack配置文件的分离
/* base.config.js 只放公共的配置,即开发和部署后都需要的配置 */
const path = require('path');
const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/main.js',output: {
//注意:这里不要直接拼接'dist'了,因为当前文件base.config.js在build文件夹下
path: path.resolve(__dirname,'../dist'),filename: 'bundle.js',},module: {
rules: [
{
test: /\.css$/,use: [ 'style-loader','css-loader' ]
},{
test: /\.vue$/,use: ['vue-loader']
}
]
},resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},plugins: [
new webpack.BannerPlugin('最终版权归polaris所有'),new htmlWebpackPlugin({
template: 'index.html'
}),// new uglifyJsPlugin()
],// devServer: {
// contentBase: './dist',// inline: true,// port:3300
// }
}
//开发需要而部署后不需要的配置
module.exports = {
devServer: {
contentBase: '../dist',inline: true,port:3300
}
}
//部署后需要的配置,但是开发时不推荐使用的配置
const uglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
plugins: [
new uglifyJsPlugin()
],}
npm install webpack-merge --save-dev
const webpackMerge = require('webpack-merge');
const baseConfig = require('./base.config.js');
module.exports = webpackMerge.merge(baseConfig,{
devServer: {
contentBase: './dist',port:3300
}
})
const uglifyJsPlugin = require('uglifyjs-webpack-plugin');
const webpackMerge = require('webpack-merge');
const baseConfig = require('./base.config.js');
module.exports = webpackMerge.merge(baseConfig,{
plugins: [
new uglifyJsPlugin()
],})
"build": "webpack --config ./build/dev.config.js","dev": "webpack-dev-server --open --config ./build/dev.config.js"