webpack的基本使用
1、安装
- npm/cnpm
全局安装 : cnpm install webpack@3.5.3 -g (4.0以上版本坑比较多,新手建议安装3.0版本) 版本号webpack -v 局部安装(在使用webpack的文件夹下) : 好处:可以在不同的项目中使用不同的webpack版本 a : 初始化仓库 npm init -y b : cnpm install webpack@3.5.3 --save-dev
2、基本概念
- 概念:webpack是一个模块打包工具;
- 作用:将浏览器不识别的拓展语言(TypeScript,Scss)转化为浏览器识别的一些语言;
- 优点:
- 代码分割:webpack支持两种依赖加载(同步和异步);
- Loaders:默认情况下,webpack只能处理JS文件,但是通过加载器我们可以把其他类型的资源转换为JS输出;
- 插件机制:当webpack内置的功能不能满足我们构建需求时,可以加载对应的插件;
- 工作流程:通过一个入口文件,找到这个入口文件所依赖的所有模块,使用loaders处理他们,将这些文件打包成一个或者多个浏览器可以识别的javascript文件;
3、基本使用
- 安装loaders
- 处理JS的loaders
cnpm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react
- 处理CSS的loaders
cnpm install --save-dev style-loader css-loader sass-loader node-sass
- 处理JS的loaders
- 安装热更新模板
热更新(文件监听) : 保存之后页面会自动更新 全局安装 cnpm install webpack-dev-server@2 -g 1)创建服务器 cnpm install webpack-dev-server@2 --save-dev 2)在package.json里面修改scripts {"dev:"webpack-dev-server --open";} 3)npm run dev 4)webpack-dev-server : 不会生成线上目录,eg:build放在内存中
- 创建一个配置文件webpack.config.js(module.exports中为相应的配置选项)
- context:用来配置基础路径(必须为绝对路径),默认情况下是当前目录;
- entry:配置要打包的入口文件,值可以是字符串、数组或者对象;
1、字符串 entry : "./entry" 2、数组(webpack会按序打包,但只会导出最后一个文件) entry : ["./entry1","./entry2"] 3、对象 entry: {//入口文件可以匹配对个 app: PATH.app,//入口文件的路径 key值app 随便 a: PATH.a }, output: {//出口文件 filename: "[name].js",//打包之后生成的文件app.js name代表入口文件的key值 也可以直接写index.js path: PATH.build//出口文件的路径/ },
- output:用来配置输出信息;
- module:模块加载的相关配置;
- module.rules:加载器数组,当依赖文件匹配指定的test模式时,webpack会自动调用数组中的相应加载器(是一个对象,有以下属性)去处理该文件,然后返回JS格式的文件;
{ test: /\.js$/,//匹配的js文件 use: {//配置项 loader: "babel-loader", options: { presets: ["@babel/env", "@babel/react"] } }, exclude: __dirname + 'node_modules/', include: [path.resolve(__dirname,'app/src'),path.resolve(__dirname,'app/test')] },
- test:正则表达式,webpack用它去匹配相应的文件,通常用来匹配文件的后缀;
- exclude:不应该被loader处理的文件;
- include:一个路径数组,这些路径会被loader处理;
- loader:文件对应的加载器;
- module.rules:加载器数组,当依赖文件匹配指定的test模式时,webpack会自动调用数组中的相应加载器(是一个对象,有以下属性)去处理该文件,然后返回JS格式的文件;
- resolve
- devServer:用来配置webpack-dev-server的行为,是一个对象,host可以用来监听指定的IP,port可以用来监听端口号等;
devServer: { host: localhost, port: 8888, open: true, proxy: { '/user': { target: 'http://10.0.0.0:8899',//目标服务器地址 ws: true, changeOrigin: true,//允许跨域 pathRewrite: {//以/user开头的地址替换为/ "^/user": "/", } } } },
- 常用插件:
- HtmlWebpackPlugin
cnpm install html-webpack-plugin --save-dev 作用:可以帮我们生成一个模板
- ProvidePlugin
ProvidePlugin可以自动加载当前模块所依赖的其他模块并以指定别名注入到当前木块中。只有你需要使用此变量的时候, 这个模块才会被 require进来。比如jQuery插件中的$或者jQuery,但是不想手动require jquery模块,因此可以用如下代码: plugins: [ new webpack.ProvidePlugin({//注册webpack的内置插件 $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", _: "lodash" }) ]
- 一个基础的webpack.config.js
const path = require("path"); const htmlWebpackPlugin = require("html-webpack-plugin"); console.log(__dirname);//D:\WEB前端\H5-1816随堂练习\第三阶段\react\day1\webpack\demo /* path.join("参数1","参数2") 将参数1和参数2的路径合并,该方法的主要用途是正确使用当前系统的 路径分隔符,Unix下为 / ,windows下为 \ path.resolve:将参数解析为绝对路径,也可以变成相对路径, 生成的路径是规范化后的,且末尾的斜杠会被删除,除非路径被解析为根目录 * */ //入口 与 出口文件路径的配置 const PATH = { app: path.join(__dirname, "./src/index.js"), a: path.join(__dirname, "./src/a.js"), build: path.join(__dirname, "./dist/js")//dist文件自动生成 } //webpack的配置 module.exports = { entry: {//入口文件可以匹配对个 app: PATH.app,//入口文件的路径 key值app 随便 a: PATH.a }, output: {//出口文件 filename: "[name].js",//打包之后生成的文件app.js name代表入口文件的key值 也可以直接写index.js path: PATH.build//出口文件的路径 /*publicPath === baseUrl : 'html://cdn.com/'//占位符,满足线上地址的需求*/ }, module: {//处理模块 js,css,img,html rules: [ { test: /\.js$/,//匹配的js文件 use: {//配置项 loader: "babel-loader", options: {//遇到es6的代码用env转为es5 react代码用react转义为js /* * babel是一个编译javascript的平台,它可以编译代码帮你达到以下目的 1、让你使用最近的javascript代码(ES6 ES7) 而不用管新的标准浏览器是否支持 2、让你使用基于javascript进行扩展语言 例如react的jsx */ presets: ["@babel/env", "@babel/react"] } }, //不需要处理的文件,如果不加,编译特别慢 排查的范围 __dirname必须存在 exclude: __dirname + 'node_modules/', include: __dirname + 'src/' }, { test: /\.(css|scss)$/, //执行顺序 从右至左 从下至上 use: ["style-loader", "css-loader", "sass-loader"] }, { test: /\.html$/, loader: "html-loader" } ] }, devServer: { host: localhost, port: 8022, open: true, }, plugins: [ new htmlWebpackPlugin({ title: "如果能够安定 有谁又愿意颠沛流离", chunks: ["index"],//指定引入哪一个js template: "./index.html",//共同的东西在模板上 filename: "index.html",//模板 打包过后生成的html文件,并自动连接js data: new Date()//扩展:如需在模板中调用htmlWebpackPlugin中的参数 可用以下方法 <%= htmlWebpackPlugin.options.属性名 %> }) ] }
- HtmlWebpackPlugin
4、与Gulp、Grunt的区别
Webpack与Gulp、Grunt没有什么可比性,它可以看作模块打包机,通过分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),
并将其转换和打包为合适的格式供浏览器使用。Gulp/Grunt是一种能够优化前端的开发流程的工具,而WebPack是一种模块化的解决方案,不过Webpack的优点使得Webpack在很多场景下可以
替代Gulp/Grunt类的工具.
5、模块
- CommonJS规范:
- 代表:Node的模块化加载;
- 环境:服务器环境,实现同步加载;
- AMD规范:
- 代表:RequireJS
- 环境:浏览器环境,实现异步加载
- ES6规范:
- 环境:浏览器与服务器环境所通用;
- 主要功能:import 与 export 以及 export default
- export:一个文件就是一个模块,外部如果想访问一个模块内部的所有变量,只能通过export对外暴露接口,暴露的接口通过名字来区分;例如在bussiness.js里面
第一种方式: export const name = "wxx"; export function square(x) { return x * x } 第二种方式: const name = "wxx"; function square(x) { return x * x } export {name , square } 注解:建议采用第二种方式,结构清晰,暴露的接口一目了然;
同时我们可以用 as 语法 进行export别名导出,让一个接口用n个名字对外暴露接口;例如 export {name as name1 , name as name2 } - import:在其他JS文件中加载使用export命令暴露的接口(文件、模块);例如在vue里面
第一种方式: import { name , square } from './bussiness.js' 第二种方式:使用 as语法 对引入的变量起别名 import { name as name1 } from './bussiness' 在vue中使用name1 第三种方式:进行整体加载,达到命名空间的效果 import * as ceshi from './bussiness' 调用:ceshi.name
export default:例如 import $ from 'jQuery'
- 引入原因:当调用模块接口时,用户必须知道export暴露了哪些接口,因此ES6引入了export default模块,允许用户自定义导入的接口名字,当然,这个模块一个文件最多有一个;
- 基础:
1、在myFunction.js文件中 export default function(){} 2、在其他文件中引入时: 引入:import myFun from './myFunction' 调用:myFun() 注解:myFun可以为任意的名字,但是切记不能像export的引入方式一样放在{}里面
- export default模块只能有一个的原因:
1、export default相当于输出一个名为default的变量或者方法,并允许我们重命名; 步骤一: function add(x,y){ return x + y; } export { add as default }; 步骤二:步骤一 等同于 步骤二 export default add import { default as myFun } from './myFunction' 步骤三:步骤二 等同于 步骤三 import myFun from './myFunction
6、遇到的问题
暂无
北栀女孩儿