内容简介:相信使用wepack的时候经常会出现下面这些疑问哈,你问我为什么要用?因为大家都在用啊:smiley::smiley:。开个玩笑,前端发展到今天,新技术新思想新框架爆发式增长,当前的浏览器环境跑不赢啊,你说你写个ES6/7在浏览器环境都能跑起来?扯淡的。这个时候
相信 webpack
这个名称对于前端的同学来说并不陌生,只要你在用 vue
、 react
等等之类的框架,就得天天和它打交道。但是大部分人都只是直接怼一个 vue-cli
脚手架生成一个项目,运行起来就开始一顿写,完全不会去看这个项目的其他相关的东西,今天开始,咱们就来说说这个又爱又恨的 webpack
问题
使用wepack的时候经常会出现下面这些疑问
- 你webpack只能打包单页面的文件吗?
- WTF,我包怎么这么大,加载太慢了
-
我打包速度怎么这么慢,什么破玩意?
…
为什么要使用webpack
哈,你问我为什么要用?因为大家都在用啊:smiley::smiley:。开个玩笑,前端发展到今天,新技术新思想新框架爆发式增长,当前的浏览器环境跑不赢啊,你说你写个ES6/7在浏览器环境都能跑起来?扯淡的。这个时候 babel
就出现了,你跑不起来是吧,那我转成 ES5
你总该跑起来吧~,那 babel
我还是不能直接用啊,肯定得借助 工具 编译呀,所以我们需要webpack去做这件事情了。
这个时候有人就要站出来说了,我gulp不服,我也能做,我就不用 webpack
。你这么说我就要跟你唠唠了,现在我们先来比较一下 webpack
和 gulp
。
gulp
是 task runner
, Webpack
是 module bundler
webpack的优势在模块化, gulp
除了模块化方面都很不错。但是前端发展至今,模块化真的很重要, CMD
、 AMD
就是模块化的产物。
简单来说,如果你当前项目需要模块化编程,那就选 webpack
,如果是处理其他事情,比如把图片拼接成雪碧图或者压缩,那么 gulp
是最擅长的
感兴趣的可以看看这个回答 gulp 有哪些功能是 webpack 不能替代的?
安装
这里可以参考 webpack官网
> mkdir webpack && cd webpack > npm init -y > npm install webpack webpack-cli -D
入口(entry)
每个 webpack
都会有一个 entry
,就是入口的意思,指示 webpack
应该使用哪个模块,来作为构建其内部依赖图的开始。
注意点:
- 入口可以有多个,如果是单页面只需要一个入口,多页面可以设置多个路口
-
入口的文件必须是
.js
文件,因为webpack
只认识js
举个:chestnut:
我们新建 webpack.config.js
和新建 src
文件夹,并且文件夹下新建 index.js
文件
目录如下
- webpack/ - src/ - index.js - webpack.config.js
webpack.config.js
module.exports = { entry: './src/index.js' };
我们上面指定 webpack
的入口文件为 index.js
文件,这是总入口
出口(output)
有入口当然就会有出口了,就是你导出的文件
webpack.config.js
module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' } };
上述 entry
已经介绍过了,我们来看看 output
,他有文件导出的路径(path)和导出的文件名(filename)
关于 filename
这里需要注意的地方有:
bundle.js filename: '[name].bundle.js'
module.exports = { entry: { app: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' } };
现在我们来试一下webapck打包
小试牛刀
第一步,新建一个文件夹webpack-demo
> mkdir webpack-demo && cd webpack-demo > npm init -y > cnpm install webpack webpack-cli -D
第二步,新建src/index.js文件和webpack.config.js文件
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist/'), }, };
index.js
document.write('hello webpack');
第三步,打包
命令行输入
> npx webpack --config webpack.config.js
然后控制台就会输出
Hash: 348dca17387cd3f29cef Version: webpack 4.33.0 Time: 227ms Built at: 2019-06-08 15:24:07 Asset Size Chunks Chunk Names bundle.js 961 bytes 0 [emitted] main Entrypoint main = bundle.js [0] ./src/index.js 33 bytes {0} [built]
看到这个信息证明你已经大功告成了,去看看dist/文件夹下是不是有打包好的js文件
最后面你会看到有黄色的警告,说mode没有设置,待会再讲
这个时候你就会想,我每次生成的文件都叫bundle.js,我都区分不开,也不好做缓存,这个时候你就需要配置一下filename了我们把webpack.config.js改成以下
const path = require('path'); module.exports = { entry: { app: './src/index.js', }, output: { filename: '[name].[hash].js', path: path.resolve(__dirname, 'dist/'), }, };
然后执行
> npx webpack --config webpack.config.js
这个时候dist/文件夹下就会多出个类似 app.32434c7cc602e3049dac.js
的文件,而且如果你反复执行打包命令,你发现app.32434c7cc602e3049dac.js文件名都没有改变,这是为什么呢?
因为webpack会判断你的文件是否有更改而来觉得文件夹hash的变更,现在你可以尝试修改一下index.js文件之后打包的效果就知道了。
模式(mode )
上面说到每次打包的时候都会报警告,告诉我们没有设置mode,现在我们来说说mode
首先mode有两个值,分别是development和production,意思就是,当前项目打包的开发环境还是生成环境的代码
如果你设置了mode: ‘development’,在项目里你可以使用 process.env.NODE_ENV 来获取当前的环境的值
你可以尝试把webpack.config.js改成以下,然后在index.js里把这个值打印出来,运行一下效果
webpack.config.js
const path = require('path'); module.exports = { mode: 'development', entry: { app: './src/index.js', }, output: { filename: '[name].[hash].js', path: path.resolve(__dirname, 'dist/'), }, };
index.js
document.write(`hello webpack,this is ${process.env.NODE_ENV}`);
现在我们只有js文件,你可以先在根目录新建一个index.html文件,把js引入在浏览器环境执行(或者直接在浏览器控制台执行js),你会看到浏览器显示 -> hello webpack,this is development
你分别运行之后会发现他们的效果是不一样的,一个是被压缩的,一个没有被压缩
这个时候你就会想了,怎么这么麻烦,我打包还得自己去新建html文件引入js然后运行或者去执行js文件,能不能让他自动运行跑起来?当然是可以的,下面我们来说说plugins
## 插件(plugins)
插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!(官网的解释)
插件怎么说呢?不好解释它,你可以理解为处理工具,插件目的在于解决 loader
(这个等会再讲,现在用不上) 无法实现的其他事
插件怎么配置?就像下面这样,当然不是随便找的插件,我们会用到下面配置的插件
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry: { app: './src/index.js', }, output: { filename: '[name].[hash].js', path: path.resolve(__dirname, 'dist/'), }, plugins: [ new HtmlWebpackPlugin({template: 'index.html'}) ] };
我们先在根目录新建一个index.html文件,之前不是说运行项目很麻烦嘛?现在教你简单的方法
然后我们用到了html-webpack-plugin,需要先安装他才能使用
> cnpm i html-webpack-plugin -D
下一步打包运行项目
> npx webpack --config webpack.config.js
运行结果:
Hash: bea857ae13cad8af6e66 Version: webpack 4.33.0 Time: 274ms Built at: 2019-06-08 16:00:33 Asset Size Chunks Chunk Names app.bea857ae13cad8af6e66.js 3.83 KiB app [emitted] app index.html 74 bytes [emitted] Entrypoint app = app.bea857ae13cad8af6e66.js [./src/index.js] 65 bytes {app} [built] Child html-webpack-plugin for "index.html": 1 asset Entrypoint undefined = index.html [./node_modules/_html-webpack-plugin@3.2.0@html-webpack-plugin/lib/loader.js!./index.html] 209 bytes {0} [built] [./node_modules/_webpack@4.33.0@webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built] [./node_modules/_webpack@4.33.0@webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built] + 1 hidden module
去查看dist文件夹下,你会发现多出了两个文件,js和index.html文件,这就是插件的功劳
html-webpack-plugin这个插件需要指定是那个html模板,然后最后打包的时候就是以这个模板为主,把打包好的js文件放到这个index.html里面,你可以查看html文件里的内容:
index.html
<script type="text/javascript" src="app.1b0b2001b0579faec32d.js"></script>
安装插件clean-webpack-plugin
> cnpm i clean-webpack-plugin -D
然后配置文件去添加插件
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { mode: 'development', entry: { app: './src/index.js', }, output: { filename: '[name].[hash].js', path: path.resolve(__dirname, 'dist/'), }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({template: 'index.html'}) ] };
然后你再去看看dist文件夹里的文件,是不是只有两个文件了?这个插件的作用是,先把dist文件夹里的文件先清空然后再把打包好的文件放入dist。
那么你还会有问题,这还是麻烦啊,我不能只运行命令行,让重新自己打开浏览器运行我打包的项目吗?当然可以啊
首先安装 webpack-dev-server
> cnpm i webpack-dev-server -D
然后
> webpack-dev-server --open --config webpack.config.js
你会发现重新自动打开了浏览器,页面显示 hello webpack,this is development。是不是很简单?
你现在可以去修改index.js然后保存文件,去浏览器看看是不是自动刷新了你刚刚更改的内容呢?
现在你可能还会有问题,我去,这太简单了吧,我要用css和图片怎么办?js不能导入css文件啊!我怎么跟vue一样在自己的ip访问项目啊?现在肯定是问题一大堆loader
loader 用于对模块的源代码进行转换。loader 可以使你在 import 或”加载”模块时预处理文件。比如可以把typescript转换成JavaScript,less转成css
现在我们就来解决你上一章节末的问题,教你配置简单的loader,来加载css或者图片
首先我们先安装css-loader/style-loader,来加载解析css文件
> cnpm i css-loader style-loader -D
下一步在src文件夹下新建test.css文件,再在index.js导入
test.css
body { background: #ccc; }
index.js
import './test.css'; document.write(`hello webpack,this is ${process.env.NODE_ENV},test`);
如果你直接运行会发现控制台报错了
ERROR in ./src/test.css 1:5 Module parse failed: Unexpected token (1:5) You may need an appropriate loader to handle this file type. > body { | background: #ccc; | } @ ./src/index.js 1:0-20
这个时候loader登场了,我们修改配置文件
webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { mode: 'development', entry: { app: './src/index.js', }, output: { filename: '[name].[hash].js', path: path.resolve(__dirname, 'dist/'), }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: 'index.html' }), ], module: { rules:[ { test: /\.css$/, use: ['style-loader', 'css-loader'], }, ] } };
然后运行命令行
> webpack-dev-server --open --config webpack.config.js
你会发现页面背景颜色变了
现在我们来说说配置:
module.rules 允许你在 webpack 配置中指定多个 loader,上面我们规定正则匹配css文件,然后如果匹配到了,则使用style-laoder和css-loader去处理css文件,css-laoder负责解析css文件,style-loader负责把css文件放到页面中去,你打开调试可以看到head里被插入了style样式标签,当前如果你想解析例如xx.ts文件,则可以在数组里面新增:
{ test: /\.ts$/, use: 'ts-loader', },
下面来看看怎么加载图片资源,还是跟上述原一样,图片也是有类型的,我们首先得匹配文件后缀,然后去用loader去解析他们,这里我们需要用到 url-loader file-loader
按照惯例先安装
> cnpm i url-loader file-loader -D
module.exports = { ... module: { rules:[ { test: /\.css$/, use: ['style-loader', 'css-loader'], }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 6000, name: 'img/[name].[hash:7].[ext]', }, } ] } };
下一步就是往项目里增加图片了
我们修改test.css文件
test.css
body { background: url(img.jpg); }
浏览器就显示的全是刚刚设置的重复图片了
这里你又会问了,不对,你这里只用到了url-loader,file-loader不是多余的吗?不是的,你可以看看options,有一个limit参数,规定如果超过了6000bytes大小的文件会交给file-loader处理,因为如果图片小于这个数值,url-loader会把图片转成base64格式的图片加载,如果超过就自己不处理了,所以他们两者是有相依性的
使用npm脚本
上面基本上都是使用一大段的命令行来执行项目,现在我们来简化一下
修改package.json
"scripts": { "dev": "webpack-dev-server --open --config webpack.config.js", "build": "webpack --config webpack.config.js" },
命令行运行项目
> npm run dev > npm run build
devServer
在开发中你可能有很多需求,比如怎么通过ip访问项目,怎么把控制台信息输出的精简点,怎么修改端口等等?这个时候就需要用到devServer的配置了
我们修改webpack.config.js,增加以下:
module.exports = { ... devServer: { contentBase: './dist', // 告诉服务器从哪里提供内容 host: '0.0.0.0', // 指定使用一个 host。默认是 localhost useLocalIp: true, // 是否使用本地ip open: true, // 是否自动打开浏览器 port: 8080, // 端口号 noInfo: true, // 显示的 webpack 包(bundle)信息」的消息将被隐藏 }, }
是的,你现在可以不用在命令行里增加–open这个参数,在这里配置也是一样的
以上所述就是小编给大家介绍的《webpack系列之初探》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。