webpack学习笔记

webpack

webpack是一个JavaScript应用的静态打包工具。

模块化

目前前端使用的一些模块化方案有:AMD、CMD、CommonJS、ES6。
在ES6之前,要想进行模块化开发,就必须借助于其他的工具,并且开发完成后还需要处理模块间的各种依赖,并且将其进行打包整合。
webpack其中一个核心就是让我们进行模块化开发,并且会帮我们处理好模块间的依赖关系。不仅仅是Js,项目的css、图片、json文件等在webpack中都可以被当做模块来使用。

ES6模块化语法

基本用法

  1. 在html中引入js文件时script标签type类型定义为module,即模块方式;
    html:
    	<script src="aaa.js" type="module"></script>
    	<script src="bbb.js" type="module"></script>
    
  2. 在a.js使用 export 导出需要导出的变量、函数、类等;
	let name = "Johan"
	function sum(a,b) {
	    return a + b
	}
	export class Person {
	    constructor(name) {
	        this.name = name;
	    }
	    run() {
	        console.log(this.name + " 在奔跑");
	    }
	}
	// 导出变量name和函数sum
	export {name, sum, Person}
  1. 在b.js使用 import 从a.js导入需要使用的变量。
	// 从aaa.js导入name变量、sum函数和Person类
	import {name, sum, Person} from "./aaa.js";
	
	console.log(name);
	console.log(sum(10,20));
	let p = new Person("JackMa");
	p.run()

其他导出导入方式

  1. 定义的同时就导出:
	export let age = 20;
	export function mul(a, b) {
	    return a * b
	}
	import {age, mul} from "./aaa.js";

	console.log(age);
	console.log(mul(10,20));
  1. 使用default导出:
    定义default导出的变量,只能导出一个
	const address = "西安市";
	export default address;

使用import导入,不需要再使用{变量名}的方式导入,名称可以自定义。

	import add from "./aaa.js";
	console.log("address: " + add)
  1. 导入文件全部内容:
    当需要从一个文件import的变量、函数很多时,每个都写在{变量名、方法名…}中会比较麻烦;
    可以使用import * as 自定义名称 from 文件路径的方法导入文件所有内容;
	import * as aaa from './aaa.js'

	console.log(aaa.name);
	console.log(aaa.sum(10,20));
	let p = new aaa.Person("JackMa");
	p.run();

打包

打包就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。并且打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6转成ES5语法,将TypeScript转成JavaScript等等操作。

对比gulp/grunt

  1. grunt/gulp的核心是Task
    我们可以配置一系列的task,并且定义task要处理的事务(例如ES6、ts转化,图片压缩,scss转成css)
    之后让grunt/gulp来依次执行这些task,而且让整个流程自动化。
    所以grunt/gulp也被称为前端自动化任务管理工具。
  2. 如下是一个gulp的task
    下面的task就是将src下面的所有js文件转成ES5的语法。
    并且最终输出到dist文件夹中。
    在这里插入图片描述
  3. 什么时候用grunt/gulp呢
    如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念。
    只需要进行简单的合并、压缩,就使用grunt/gulp即可。
    但是如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更加强大的webpack了。
  4. 所以,grunt/gulp和webpack有什么不同呢
    grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。
    webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能。

安装webpack

首先需要安装node,版本需要不能低于8.9。

  1. 查看node版本:
    在这里插入图片描述

  2. 全局安装webpack3.6.0:
    在这里插入图片描述

  3. 局部安装webpack:
    ① cd 对应目录;
    ② 执行npm install webpack@3.6.0 --save-dev:
    在这里插入图片描述
    –save-dev`是开发时依赖,项目打包后不需要继续使用的。

  4. 为什么全局安装后,还需要局部安装呢?
    ① 在终端直接执行webpack命令,使用的全局安装的webpack。
    ② 当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack。

基本使用

文件和文件夹解析:
dist文件夹:(distribution 发布)用于存放之后打包的文件。
src文件夹:用于存放我们写的源文件。
main.js:项目的入口文件。具体内容查看下面详情。
aaa.js:定义了一些数学工具函数,可以在其他地方引用,并且使用。具体内容查看下面的详情。
index.html:浏览器打开展示的首页html
package.json:通过npm init -y生成的,npm包管理的文件(暂时没有用上,后面才会用上)

src目录每个js文件都采用模块化的思想开发,具体模块化规范CommonJS、AMD、ES6等都可以,最终使用webpack打包,webpack会把源码转换为浏览器可以解析的代码。
在这里插入图片描述

  1. 模块文件aaa.js:
	const name = "JoHan";
	// 1. CommonJS 语法
	module.exports = {name};
	
	// 2. ES6语法
	export {name}
  1. 主文件 main.js:
	// 1. CommonJS 语法
	const {name} = require("./aaa.js");
	
	// 2. ES6语法
	import {name} from "./aaa";
	
	console.log(name);
  1. 命令行使用webpack src/main.js dist/bundle.js,将main.js打包成bundle.js。 main.js依赖的aaa.js也会处理。
    在这里插入图片描述
  2. index.html中引用打包后的js文件:
	<script src="dist/bundle.js"></script>

配置webpack.config.js和package.json

配置webpack.config.js

  1. 每次使用webpack的命令都需要写上入口和出口作为参数会非常麻烦。

    新建webpack.config.js文件:

	// path 是node.js的系统库
	const path = require("path");
	
	module.exports = {
	    entry: "./src/main.js",
	    output: {
	        // path需要填写绝对路径
	        path: path.join(__dirname, "dist"),
	        filename: "bundle.js"
	    }
	};

然后直接使用webpack不需要再带上路径,就可以进行打包;
在这里插入图片描述

局部安装webpack

  1. 因为一个项目往往依赖特定的webpack版本,全局的版本可能很这个项目的webpack版本不一致,导出打包出现问题。
    所以通常一个项目,都有自己局部的webpack。
    这里我们让局部安装webpack3.6.0。Vue CLI3中已经升级到webpack4,但是它将配置文件隐藏了起来,所以查看起来不是很方便。
    注: 在cmd或者webstorm的命令直接使用webpack打包都是使用的全局webpack。
    在这里插入图片描述
    项目目录会生成node_modules目录,里面存放的node默认的包和下载的包:
    在这里插入图片描述

  2. 使用局部webpack打包:
    在这里插入图片描述

配置package.json

配置完局部webpack后,还需要指定局部webpack路径才能进行打包 node_modules.bin\webpack;
可以再package.json的script中定义自己的命令:
package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。
① 会寻找本地的node_modules/.bin路径中对应的命令。
② 如果没有找到,会去全局的环境变量中寻找。

在package.json中定义build命令,对应的值就是webpack,因为会优先去本地webpack中找命令,所以这使用的是局部webpack打包。在这里插入图片描述
通过npm run build执行打包:
在这里插入图片描述

webpack打包css文件的配置

loader概念

在开发中不仅有基本的js代码处理,也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等。
对于webpack本身的能力来说,对于这些转化是不支持的。需要给webpack扩展对应的loader
loader使用过程:
步骤一:通过npm安装需要使用的loader
步骤二:在webpack.config.js中的modules关键字下进行配置

大部分loader我们都可以在webpack的官网中找到,并且学习对应的用法。
参考官方文档: https://www.webpackjs.com/loaders/css-loader/

基本使用

新建css目录用于存放样式文件;
js目录用于存放js文件,main.js还是放在根目录下;
在这里插入图片描述

  1. 安装loader:
    style-loader: 将模块的导出作为样式添加到 DOM 中。
    css-loader:解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码。
    npm install --save-dev style-loader
    npm install --save-dev css-loader

  2. 在webpack.config.js中配置loader:

	module.exports = {
	  module: {
	    rules: [
	      {
	        // 匹配css文件
	        test: /\.css$/,
	        use: [ 'style-loader', 'css-loader' ]
	      }
	    ]
	  }
	}

在这里插入图片描述

  1. 在main.js中引用css文件,这样打包时才会找到依赖关系:
	// 引用css
	require("./css/main.css")
  1. 使用npm run build重新打包。

webpack打包css文件的配置

  1. 安装 less-loader和less:
    less-loader:加载和转译 LESS 文件。
    less:webpack会使用less对less文件进行编译。

  2. 在webpack.config.js中配置loader:

	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
	            }]
	        }]
	    }
	};

在这里插入图片描述
3. 创建less文件:
在这里插入图片描述
4. 在main.js中引用less文件:

	// 引用less
	require("./css/special.less")

webpack打包图片等静态文件

  1. 安装 url-loader

    官方文档:https://www.webpackjs.com/loaders/url-loader/
    进入项目目录执行:npm install --save-dev url-loader
    在这里插入图片描述

  2. 在webpack.config.js中配置loader:

	module.exports = {
	  module: {
	    rules: [
	      {
	        test: /\.(png|jpg|gif|jepg)$/,
	        use: [
	          {
	            loader: 'url-loader',
	            options: {
	              limit: 8192
	            }
	          }
	        ]
	      }
	    ]
	  }
	}

在这里插入图片描述

  1. 在css中设置body的图片背景:
    在这里插入图片描述
  2. 重新打包: npm run build。
  3. 查看页面background设置的背景图片自动转换为了base64编码字符串:
    图片的base64编码字符串:图片的base64编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址。我们所看到的网页上的每一个图片,都是需要消耗一个 http 请求下载而来的。图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,而可以随着 HTML 的下载同时下载到本地那就太好了,而 base64 正好能解决这个问题。

在这里插入图片描述

  1. 如果图片大于limit的限制,需要安装file-loader:
    6.1 将css中背景图片缓存大于30k的test02.jpg,重新打包:

    在这里插入图片描述
    6.2 会报错找不到file-loader:
    在这里插入图片描述

    6.3 执行命令安装file-loader(不需要其他配置):npm install --save-dev file-loader
    6.4 安装完成后重新打包,会在dist目录下生成一张新图片:
    在这里插入图片描述
    6.5 刷新页面,报错找不到新生成的图片:
    查看报错信息,是去根目录找图片,而没有去dist目录;
    在这里插入图片描述
    6.6 配置publicPath—图片加载路径:
    官方文档:https://www.webpackjs.com/configuration/output/#output-publicpath
    在这里插入图片描述
    6.7 重新打包。

  2. 设置图片打包名称及位置:
    默认的图片打包是会在dist目录下生成一张新图片,名称为32位哈希。这样把图片都放在dist根目录显得很乱,并且32位哈希太长,也看不出和原图片对应关系。
    通过配置webpack.config.js可以指定生成图片的目录、名称:

在这里插入图片描述
如下:自动创建了img目录,并且图片名称是“原图片名称-8位hash.原扩展名”:
在这里插入图片描述

webpack转换ES5语法

  1. 查看转换后的js文件,其中还是es6的语法,有些浏览器可能不支持,所以要将其转换为es5的语法:
    在这里插入图片描述
  2. 将ES6的语法转成ES5,那么就需要使用babel。而在webpack中,直接安装babel对应的loader就可以了。
    执行: npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
    官方文档: https://www.webpackjs.com/loaders/babel-loader/
  3. 配置webpack.config.js:
    在这里插入图片描述
  4. 查看重新打包后的js文件没有es6的语法:
    在这里插入图片描述

webpack中使用Vue

  1. 模板写在index.html中:
	<body>
	    这是首页
	    <div id="app">
	        <h2>{{message}}</h2>
	        <button>按钮</button>
	    </div>
	    <script src="dist/bundle.js"></script>
	</body>
  1. 从index.html抽出模板,放在js中:
    在这里插入图片描述
  2. 从主app进一步抽取到组件中:

main.js:

	// 引用vue
	import Vue from 'vue'
	// 定义组件---抽取模板、数据到组件中
	const App = {
	    template: `
	        <div>
	            <h2>{{message}}</h2>
	            <button>按钮</button>
	        </div>
	    `,
	    data() {
	        return {
	            message: "Hello webpack"
	        }
	    }
	};
	
	new Vue({
	    el: "#app",
	    		  // 使用组件
	    template: `<App></App>`,
	    components: {
	    	// 注册组件
	        App
	    }
	})
  1. 从main.js 抽取到其他js文件中:
    aaa.js
	// 导出组件
	export default {
	    template: `
	        <div>
	            <h2>{{message}}</h2>
	            <button>按钮</button>
	        </div>
	    `,
	    data() {
	        return {
	            message: "Hello webpack"
	        }
	    }
	};

main.js导入aaa.js:

	// 引用vue
	import Vue from 'vue'
	// 导入aaa.js中的App
	import App from './js/aaa'

	new Vue({
	    el: "#app",
	    template: `<App></App>`,
	    components: {
	        App
	    }
	})
  1. 最终方案— .vue文件创建组件:
    5.1 创建vue组件目录和App.vue文件:
    在这里插入图片描述
    5.2 .vue文件包含三部分,template中写组件模板;script中写组件代码;style中写组件样式:
    将aaa.js中定义的App组件迁移到App.vue中,组件的内容写在对应模块。
    在这里插入图片描述
    5.3 在main.js中导入App.vue组件:

    	// 引用vue
    	import Vue from 'vue'
    	// 导入App.vue组件
    	import App from './vue/App.vue'
    	new Vue({
    	    el: "#app",
    	    template: `<App></App>`,
    	    components: {
    	        App
    	    }
    	});
    

    5.4 重新打包,报错需要loader编译.vue文件:
    在这里插入图片描述
    5.5 安装vue-loader和vue-template-compiler:
    执行: npm install vue-loader vue-template-compiler --save-dev
    5.6 配置webpack.config.js文件:

         {
             test: /\.vue$/,
             use: ['vue-loader']
         }
    

    5.7 重新打包,报错vue-loader需要其他插件:

    在这里插入图片描述

    5.8 这是因为安装的vue-loader是15.9.1版本,14版本以上还需要安装其他插件,这里先把版本改为13.0.0,修改package.json后执行npm install重新安装:
    在这里插入图片描述
    5.9 重新打包:
    在这里插入图片描述
    5.10 如果想导入vue组件时,省略.vue后缀,需要配置webpack.config.js:
    在这里插入图片描述
    在这里插入图片描述

webpack中使用插件Plugins

loader和plugin区别

loader主要用于转换某些类型的模块,它是一个转换器。
plugin是插件,它是对webpack本身的扩展,是一个扩展器。

plugin的使用过程:

  1. 通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
  2. 在webpack.config.js中的plugins中配置插件。

添加版权的Plugin

  1. 配置web.config.js,导入webpack,配置plugins参数:
    在这里插入图片描述
  2. 重新打包,查看bundle.js,已经包含了设置的版权信息:
    在这里插入图片描述

打包html的plugin

  1. 当前index.html文件还是是存放在项目的根目录下的。但是,在真实发布项目时,发布的是dist文件夹中的内容,但是dist文件夹中如果没有index.html文件,那么打包的js等文件也就没有意义了。
    所以,需要将index.html文件打包到dist文件夹中,这个时候就可以使用HtmlWebpackPlugin插件
  2. HtmlWebpackPlugin插件的作用:
    ① 自动生成一个index.html文件(可以指定模板来生成)
    ② 将打包的js文件,自动通过script标签插入到body中
  3. 安装HtmlWebpackPlugin插件
    执行:npm install html-webpack-plugin@3.2.0 --save-dev
  4. 在webpack.config.js配置HtmlWebpackPlugin插件:
    在这里插入图片描述
    5.重新打包,dist目录下已经包含了index.html,并且添加script标签对bundle.js的引用:
    在这里插入图片描述
  5. 如上,存在两个问题:
    ① 当前index.html已经在dist目录下, 引用bundle.js时不需要再加dist/。有这个dist目录的原因是,最开始index.html还在src目录时,生成的图片引用时没有加dist目录,解决办法是在webpack.config.js中添加了publicPath,现在index.html已经打包到了dist目录,只需要把publicPath删掉即可。
    在这里插入图片描述
    ② 没有定义 div id=“app”。
    在配置webpack.config.js中的HtmlWebpackPlugin配置template参数,指定按照哪个html来生成index.html。这里指定同级目录下的index.html。
    另外,由于会自动加上bundle.js的引用,所以原index.html中的script可以删掉。重新打包,运行dist下新生成的inde.html。
    在这里插入图片描述

压缩JS插件

在项目发布之前,需要对js等文件进行压缩处理,对打包的js文件进行压缩使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致。

  1. 安装:
    执行命令:npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
  2. 配置webpack.config.js,导入uglifyjs-webpack-plugin,重新打包:
    在这里插入图片描述
    在这里插入图片描述

搭建本地服务器

webpack提供了一个可选的本地开发服务器,基于node.js搭建,内部使用express框架,可以实现让浏览器自动刷新显示代码修改后的结果。
不过它是一个单独的模块,在webpack中使用之前需要先安装它。
这个服务器是把打包的文件加载在内存中,并不会刷新到磁盘中。

  1. 安装webpack-dev-server
    执行命令: npm install --save-dev webpack-dev-server@2.9.1

  2. 配置dev-server
    devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:
    contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist。
    port:端口号(默认8080)。
    inline:页面是否实时刷新。
    historyApiFallback:在SPA页面中,依赖HTML5的history模式。
    在这里插入图片描述

  3. 配置启动命令:
    在package.json中配置dev指令,然后通过npm run dev启动服务。
    在这里插入图片描述
    在这里插入图片描述

拆分开发和生成环境配置

有些配置是开发环境需要的,有些是生成环境才需要的。如下,devServer是开发环境才需要的,uglifyjsWebpackPlugin是生成环境才需要的。
在这里插入图片描述

  1. 新建build目录
    创建base、prod、dev.config.js文件,分别对应公共配置、生成环境配置、开发环境配置,并把对应配置抽离到对应文件中:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  2. 安装webpack-merge
    执行命令: npm install webpack-merge --save-dev

  3. 使用webpack-merge合并配置文件
    prod.config.js:

    	const uglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin");
    	// 导入webpack-merge模块
    	const webpackMerge = require("webpack-merge");
    	// 导入baseConfig
    	const baseConfig = require("./base.config");
    	// 合并
    	module.exports = webpackMerge(baseConfig, {
    	    plugins: [
    	        new uglifyjsWebpackPlugin()
    	    ]
    	});
    

    dev.config.js:

    	// 导入webpack-merge模块
    	const webpackMerge = require("webpack-merge");
    	// 导入baseConfig
    	const baseConfig = require("./base.config");
    	// 合并
    	module.exports = webpackMerge(baseConfig, {
    	    devServer: {
    	        contentBase: "./dist",
    	        inline: true
    	    }
    	});
    
    1. 自定义配置文件路径:
      删除根目录的webpack.config.js文件,在package.json中配置配置文件路径:
      在这里插入图片描述
  4. 修改打包输出路径:
    之前webpack.config.js在根目录,其中配置了打包输出路径为“webpack.config.js拼接dist目录”。由于现在配置文件已经放在build目录,所以需要修改路径,否则会打包在build/dist目录。 在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值