前端使用的一个模块打包工具:https://webpack.js.org/
webpack安装
- 安装 node & npm(因为webpack是基于node开发的)
- 通过 npm / yarn 的方式来安装 webpack
安装方式:
- 全局安装
- npm install -g webpack
- -g : global 全局
- 会装在npm默认目录
- 好处:只需要安装一次,本机中任何项目都可以直接使用
- 缺点:如果本机项目中所依赖的webpack版本不一致会有一些问题。
- 官方推荐安装 本地(根据当前项目来安装)
- 本地安装
- npm install –save-dev webpack
- 可在node_modules 目录中查找;
- 不同项目可使用不同版本。
- 全局安装
模块化
- 把具有一定独立功能的代码放到一个单独的文件中,每一个文件就是一个模块。
- 优势:管理方便、易于复用
- 解决:项目开发过程中的冲突、依赖
node出现以后,node必须有模块化,node实现了一个简易的模块框架,并流行起来,同时为其定义一些标准:
CommonJS规范
CommonJS规范是适合使用在服务端的,是同步加载,客户端(浏览器)并不适合使用,所以后来有人就参考CommonJS规范定义一些适用于web的模块化规范:
- 1.AMD(Asynchronous Module Definition),前置依赖。
- 适用于浏览器。
- 基于AMD的requireJS模块化库
- 2.CMD(Common Module Definition),CMD则是依赖就近。
- 适用于服务器
- 基于CMD的seaJS模块化库
注意:自从出来后ES6,AMD及CMD基本不用了,而是用ES6中自带的模块化。
ES6模块化
- 基本规则
- 1:每一个模块只加载一次, 每一个JS只执行一次, 如果下次再去加载同目录下同文件,直接从内存中读取。 一个模块就是一个单例,或者说就是一个对象;
- 2:每一个模块内声明的变量都是局部变量,不会污染全局作用域;
- 3:模块内部的变量或者函数可以通过export导出;
- 4:一个模块可以导入别的模块
- 语法
- 导出:return、exports、ES6->export
- 导出:return、exports、ES6->export
- 导入:require、ES6->import
- http://www.ecma-international.org/ecma-262/8.0/index.html#table-42!
说明:
1. export var a=100
,那么对应的写法可以用*号的方式去导入,如import * as m1 from './2';
;“as m1”意思是取一个别名叫做“m1”,或者import {a} from './2';
2. 用*号的导入方式,对应的导出方式可以是任意的。它得到的是一个Object对象
- 1.js:import * as m1 from './2';
,“./2”实际是“./2.js”,可不写后缀。
- 2.js:export var a=120;
3. 举例:
- 1.js:
<code>
/ 导出一组数据
var a = 100;
var b = 200;
var c = function() {};
export {a, b, c}
</code>
- 2.js: ``` import {a, b, c} from './2';```</br>
也就是说如果要用{}的形式导入,那么接收的时候就需要注意:导出的名字和接收的名字是对应的,类似解构赋值。
Babel是一个javascript编译器,也是用node写的,可以将ES6+转换成Es5,但并不解析代码中的 import 或 require 指令。因此,我们需要一个打包工具,可用webpack。
webpack配置
webpack可以将AMD、CMD及ES6模块化代码编译成CommonJS。
1.图示:
2.核心概念
- 1.入口(entry)
- entry:指定我们的项目打包文件的入口文件
- entry可以接收:[string, array, object]三种类型。
- 如果我们的应用程序只有一个入口的时候,可以直接使用字符串形式
- 如果我们的程序有多个入口,那么可以使用数组或者对象形式
- 单文件:一个入口
- 单文件多入口:数组:index.html 加载了两个或多个js
- 多文件多入口:对象
//entry: ‘./src/1.js’,
2.输出(output):指定打包后的文件生成配置
- 1.打包后的文件存放的目录:
path: path.resolve(__dirname, “dist”),
- __dirname : 常量,返回当前文件所在的绝对路径
- path.resolve:返回(处理)不同操作系统的绝对路径问题
2.生成后的文件名:
- (1)对于单个入口起点,filename 会是一个静态名称。filename: ‘bundle.js’;
(2)当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin)创建多个 bundle,应该使用以下一种替换方式,来赋予每个 bundle 一个唯一的名称:
- a.入口名称: filename: “[name].bundle.js”;
- 、、、、、、
d.使用基于每个 chunk 内容的 hash:filename: “[chunkhash].bundle.js”
注意:使用hash值做文件名,是为了使每次打包生成的文件的文件名不一样,解决JS缓存问题。<code> const webpack=require("webpack"); const path=require("path"); module.exports={ entry:{ a:"./src/1.js" }, output:{ path:path.resolve(__dirname,"dist"), filename:'bundle.js' } }; </code>
- 1.打包后的文件存放的目录:
3.loader
(1) 文件打包预处理器,webpack首先会去加载指定文件(css、js、html、txt、png等)各种资源文件,然后进行打包,但是webpack本身只能处理js,像css被打包后可能就会运行出错,Loader就派上用场了,Loader其实就是打包预处理器。
预处理:预先处理,webpack会调用各种Loader对非js的资源进行预先处理,处理完成(处理成js能够识别的数据)以后交给webpack进行打包。(2) 在使用loader之前需要安装指定的loader:npm install loader。
- (3)loader 也能够使用 options 对象进行配置。
(4)在 webpack.config.js 文件中进行配置:
rules:配置Loader加载和处理规则;test: /\.txt$/
被加载的资源文件的后缀,use: ‘raw-loader’;
当加载的资源满足test的时候,调用use指定的loader去该资源进行解析处理。<code> { ..., //配置第三方模块,比如Loader就在这里配置 module: { rules: [ //每一个规则是一个对象 { test: /\.txt$/, use: 'raw-loader' } ] } } </code>
(4)常用的loader
- (1)raw-loader:处理源数据;
(2)file-loader: 解析并返回文件的路径;
<code> { test: /\.png$/, //use: 'file-loader' use: [ { loader: 'file-loader', options: { name: '[name].[ext]' } } ] } </code>
(3)url-loader:像 file loader 一样工作,但如果文件小于限制,可以返回 data URL
<code> { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { // 设置小于limit值生成dataURL,否则生成url limit: 819200 } } ] } </code>
- (4)css-loader:解析 CSS 文件后,使用 import 加载,并且返回CSS代码;
(5)style-loader:将模块的导出作为样式添加到DOM中;
<code> { test: /\.css$/, use: [ // 从下向上执行,所以别写反了!!! 'style-loader', 'css-loader' ] } </code>
- (5)json-loader
注意:webpack >= v2.0.0 默认支持导入 JSON 文件,不需再下载json的loader。
4.插件(plugins)
和Loader类似,但是他是打包后执行,对打包后的文件做进一步的处理。- 压缩插件:webpack.optimize.UglifyJsPlugin是webpack的核心插件,是自带的,直接使用。
UglifyJsPlugin与webpack.optimize.UglifyJsPlugin功能相同,但是需要安装插件才能用。 - ExtractTextWebpackPlugin:从 bundle 中提取文本(CSS)到单独的文件。
如下文代码所示,它会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。
- 压缩插件:webpack.optimize.UglifyJsPlugin是webpack的核心插件,是自带的,直接使用。
- 1.入口(entry)
2.配置:webpack.config.js
<code> const path = require('path'); const webpack = require('webpack'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { UglifyJSPlugin: './src/UglifyJSPlugin.js' }, output: { path: path.resolve(__dirname, "dist"), filename: '[name].bundle.js', //filename: '[chunkhash].bundle.js' // 设置打包后的资源的加载 publicPath: "./dist/" }, module: { rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) } ] }, // 插件配置 plugins: [ new webpack.optimize.UglifyJsPlugin(), new ExtractTextPlugin("styles.css") ] }; </code>
本地webpack运行
方法一:
1.在 package.json 添加一个 npm 脚本(npm script);
<code> { ... "scripts": { "build": "webpack -w" }, ... } </code>
- 2.运行“npm run build”命令,可得到如下图所示:
- 方法二:
在当前目录下,运行“.\node_modules.bin\webpack -w”命令。
注意:”webpack -w”中的“-w”命令是监听相关文件是否被修改,若修改则自动重新运行webpack,不用再自己手动重启。
全局webpack运行
在当前目录下,运行“webpack -w”命令。
模块热替换
模块热替换,Hot Module ReplaceMent(HMR)。
- 可以在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。效果上就是界面的无刷新更新。
- 这个功能主要是用于开发过程中,对生产环境没有什么帮助。
- 过程:
- (1)首先需要安装Webpack-dev-server,一个轻量的node.js express服务器。
“npm install webpack-dev-server –save-dev”
注意:Webpack-dev-server十分小巧,这里的作用是用来伺服资源文件,不能替代后端的服务器。
- (1)首先需要安装Webpack-dev-server,一个轻量的node.js express服务器。
复制本目录下的 package.json 和 webpack.config.js 文件
// package.json
<code>
{
"name": "003",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --env development",
"dev": "webpack-dev-server --env development",
"build": "webpack --env production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^2.28.0",
"webpack": "^2.3.2",
"webpack-dev-server": "^2.4.2"
}
}
</code>
// webpack.config.js
<code>
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devServer: {
host: process.env.HOST, // Defaults to `localhost`
port: 8080, // Defaults to 8080
},
entry: {
app: "./app/app.js",
},
output: {
path: path.resolve(__dirname,"build"),
filename: '[name].js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'hot replace',
}),
],
};
</code>
npm i
npm run dev 或者 npm run start 这些可以在 package.json 中配置
浏览器打开 localhost:8080 端口号可以在webpack.config.js 中配置
热模块打包的资源是存在于内存中的
使用热模块能为我们的开发带来很多便利