直入主题吧,建个文件夹webpack-tut并进入,打开cmd命令窗口,执行npm init -y 命令,建立package.json 文件,转化为了node 项目,这样好管理依赖和版本什么的。此时能够学习webpack了。首先要安装webpack,不过这里要注意,webpack4 把webpack 命令单独抽了出来,造成了一个单独的包webpack-cli ,咱们安装webpack的同时要把它安装上css
npm install webpack webpack-cli --save-dev
webpack命令,就是咱们在命令窗口中写的命令,咱们在cmd 命令窗口中,输入webpack, 就会把打包,webpack 就是一个命令。为何要单独造成一个包呢?由于webpack-cli 还提供了两个其它的功能,init 和 migrate命令,使咱们快速建立webpack 配置和提供升级迁移。不过这两个基本不用,了解一下就能够了。咱们只要记住安装webpack的同时安装上webpack-cli就能够了。html
webpack 是模块打包工具,那就建几个文件让它打包,在webpack-tut 文件夹中新建一个src 文件夹,存放咱们的源文件,再在src 文件夹中新建index.js 文件和component.js 文件,component.js 文件前端
export default (text = 'hello world') => { const element = document.createElement('div'); element.innerHTML = text; return element; }
index.js 文件node
import component from './component';
document.body.appendChild(component());
怎么打包呢?在webpack4 下,直接执行webpack 命令。在package.json的scripts的字段中,写上 “build”: “webpack”, 执行npm run build 命令,生成了dist 目录,表示打包成功了,但也发现了一个WARNINGwebpack
Webpack4 提供了一个mode 配置项 ,它有两个选择: production 和 development, 就是生产模式和开发模式,不一样模式,配置确定不同。mode 能够在命令行进行配置, build 命令改为 webpack --mode production 或 webpack --mode development,就配置成功了。ios
以上就是webpack4 提供的零配置。简单总结一下,当执行webpack命令,而又没有配置文件时,webpack会寻找默认的入口文件。默认的入口文件就是项目根目录下的src目录下的index.js文件,这也是新建src 目录和把js文件命名为index.js 的缘由。打包后文件,它也定义了默认的输出路径,打包后的文件放到dist 目录中, 文件名为main.js 文件, 同时,它还会根据你指定的mode 进行打包优化。web
对于小型的项目,零配置没有问题,但对于大型的web 项目,它不光有js, 还有css, image 等,零配置就无能为力,仍是要退回写webpack的配置文件。在webpack-tut中新建webpack.config.js 文件(配置文件的默认名称),配置文件和之前相同,都是entry, output, module, plugins选项。 零配置的时候,webpack 给咱们提供了entry 和output, 若是以为ok的话,可使用,那配置文件中,只写module 和plugins 就能够,若是以为不ok 的话,能够写entry 和output, 把它覆盖掉,这都没有问题, mode 的配置也是如此,能够在命令行中指定,也能够在配置文件中书写,如今用配置文件的方式,把零配置实现一下正则表达式
const path = require('path'); module.exports = { mode: 'development', entry: path.join(__dirname, 'src/index.js'), output: { path: path.join(__dirname, 'dist'), filename: 'main.js' } }
npm run build 也打包成功了,最后验证一下,在根目录下建一个html 文件,script 引入 dist/main.js, 没有问题。但这时你也会发现一个问题,改动js文件后,都要执行npm run build 命令,同时要手动刷新浏览器才能看效果,很是麻烦,不利于开发,怎么办? 使用webpack-dev-server, 自动打包,自动刷新npm
webpack-dev-server 是 webpack自带的一个小型服务器,它会检测每一个文件的变更,每当有文件改动时,它就会从新打包,而后浏览器会自动刷新页面,这样就能够时时看到代码的变更,大大开发了开发效率。这也是所谓的liveload 或hotload(热更新)。但这里要注意,webpack-dev-server 打包后文件是放到内存中的,而不像npm run build 把文件打包到硬盘上,默认状况下,webpack会把打包生成的文件生成到根目录下,就至关于在根目下多了打包后的文件,能够经过开发者工具的source 面板来查看一下。json
首先 npm install webpack-dev-server --save-dev 安装它,而后在scripts中,"dev": "webpack-dev-server",
npm run dev 启动服务器,但当咱们更改代码,页面刷新但内容并无进行改变,这是由于index.html 里面访问的js 文件是 dist 文件夹中的main.js, 而不是webpack 打包后生成的文件。把dist 文件夹删除,页面直接报错了,找不到main.js 文件,上面已经说了,webpack-dev-server 会把文件打包到项目根目录下,因此index.html 文件中应该引入当前文件夹下面的main.js。
<body> <script src="./main.js"></script> </body>
npm run dev 和npm run build 命令下,index.html 引入的js 文件路不一致,可使用html-webpack-plugin 插件解决。npm install html-webpack-plugin --save-dev 安装,
插件的使用方式也简单,配置文件中有一个plugins 属性,它是一个数组,每个用到的插件都是数组中的一项。具体到每个插件呢?插件都会暴露出构造函数,经过new 调用,就可使用,若是插件还有配置项,它就给构造函数传递参数,只传一个对象做为参数
const path = require('path'); const htmlWebpackPlugin = require('html-webpack-plugin'); // 引入插件 module.exports = { mode: 'development', entry: path.join(__dirname, 'src/index.js'), output: { path: path.join(__dirname, 'dist'), filename: 'main.js' }, plugins: [ new htmlWebpackPlugin({ // 插件的使用: new 调用构造函数,配置项就是构造函数的参数(对象形式的参数) template: 'index.html' }) ] }
这时npm run dev 和npm run build都没有问题。这时我想对webpack-dev-server 进行配置,好比把端口改成9000, 配置文件提供了一个devServer 配置项,这个配置项和entry, output,module并列。devServer的配置是很庞大人,这里只是学几个简单实用的配置
module.exports = { devServer: { port: 9000, // 设置端口号 stats: 'errors-only', // 只有产生错误的时候,才显示错误信息,日志的输出等级是error. overlay: true // 当有编译错误的时候,在浏览器页面上显示。 }, plugins: [ new htmlWebpackPlugin() ] }
重启服务器,这时看到项目启动在9000端口下。
这时你也应该发现了一个问题,就是当咱们修改配置文件的时候,咱们都要从新启动服务器,这有点麻烦,是否是能够监听配置文件的变化,自动重启服务器,这就要用到nodemon, nodemon 就是监听文件变化,重启服务器的。先安装nodemon, npm install nodemon --save-dev, 而后把 dev 命令改成下面
"dev": "nodemon --watch webpack.config.js --exec \"webpack-dev-server \""
命令的意思是 监听webpack.config.js 的变化,而后执行(exec) webpack-dev-server 命令,注意\'' 双引号的转义。
webpack-dev-server 还有两个配置项须要注意一下:
contentBase: webpack-dev-server 会把全部的静态文件(css, js, img 等)进行打包,放到服务器根目录下,供咱们访问。但咱们能够访问服务器中的任何资源,一旦这些资源不是由webpack-dev-server 打包生成的,咱们就要指定这些非打包生成的静态资源,好比index.html 文件,的位置,也就是contentbase,不然就会显示404. 若是不使用webpack-html-plugin, webpack 是不会打包生成index.html的, 那咱们就要手动建立index.html, 这时index.html 文件,就是非webpack-dev-server 打包生成的资源,咱们就要指定它的位置。由于咱们在浏览器中输入localhost:8080, 咱们是向webpack-dev-server 请求index.html 资源,webpack-dev-server 并无生成这个文件,因此就会报错,若是告诉webpack-dev-server, index.html 在什么地方,它就会去找,就不会报错了。这就是contentbase的做用,webpack-dev-server 会向contentbase 指定的目录去找它没有打包生成的文件,你可能说,咱们手动建立index.html时,也没有指定contnetbase, 整个项目也没有问题,这是由于contentbase的默认值是项目根目录,而咱们建立的index.html 恰巧也在项目根目录下,因此没有问题。若是咱们在项目根目录下新建一个文件夹叫public, 而后把index.html 放到里面,你再运行webapck-dev-serve , 它就会报错,这时就要指定contentbase, 它的取值就很清楚了,index.html(非webpack-dev-server 打包的资源)所在的位置, 绝对路径和相对路径均可以, 相对路径"build", 它是相对于项目根目录的, 绝对路径,path.join(__dirname, ‘public’)
proxy: 代理,作过先后端联调,都知道代理的做用。当咱们在本地开发的时候,访问的服务器是localhost. 可是后端的代码却在同事的电脑上,咱们要访问同事的服务,就要设置代理了,要否则访问的永远都是本地的服务localhost,一个接口都没有。咱们在请求的接口面前加一个标识,如axios.post(‘/api/login’), /api 就是标识,而后咱们再在proxy 配置项里面给这个标识配置一个代理到的真实路径,如 ‘/api’ : ‘http://102.03.34.58/api’, 那么当咱们调用接口的时候,实际上变成了http://102.03.34.58/api/login, 代理配置中的真实路径,就是会替换到请求中的标示
module.exports = { devServer: { contentBase:'build', proxy: { '/api': 'http://102.03.34.58/api' }, port: 9000, // 设置端口号 stats: 'errors-only', // 只有产生错误的时候,才显示错误信息,日志的输出等级是error. overlay: true // 当有编译错误的时候,在浏览器页面上显示。 }, plugins: [ new htmlWebpackPlugin() ] }
但有时候,多是多个同事进行开发,接口没有那么规范,可能有的以api 开始,有的没有api, 根本就没有统一的标识,以上这种配置方式确定不行, '/api' 标识还能够是一个对象
proxy: { '/api': { target: 'http://102.03.34.58', pathRewrite: { '^/api': '' } } }
这里要注意target 是请求的服务器地址,后面没有api, 使用这种方式配置之后,代理会在前端请求中的/api前面加上target, 至关于仍是请求了 http://102.03.34.58/api/login,因此这里增长了pathRewrite 路径重写,全部以/api 开头的路径都转化为 空,因此最后真实的请求路径中 http://102.03.34.58/login. pathRewrite 中的属性是正则表达式,^以什么开始, 值 呢?就是匹配到的路径重写成会什么。
proxy 中的属性'/api', 是前端发送请求时,请求接口中的url要加的参数,当真正发送请求时,webpack 服务中配置的代理碰到api 就会拦截,而后把它变成咱们配置的真实的路径