Webpack是一个前端资源加载(模块加载器)兼打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
grunt/gulp是优化前端开发流程的工具,webpack是一种模块化解决方案,为了解决可以require不同文件的需求引入了loader,初衷是require everything, bundle everything。webpack的plugins选项挤掉了gulp的市场,而npm/package.json里面的scripts很好用,调用任务写一个简单的命令就行。
grunt、gulp的工作方式:在一个配置文件中,指明对某些文件进行编译,组合,压缩,之后工具会自动完成这些步骤。
webpack的工作方式:通过一个主文件index.js,查找项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。
温馨提示:本篇文章以webpack1.x为例来入门学习webpack。
一、webpack的安装
cnpm是啥东西?电脑系统识别这个命令吗?请看这里。
保证把nodejs,npm,cnpm都安装好后,下面开始安装webpack。可以用windows系统的命令行,也可以用git bash。
cnpm install webpack -g
二、webpack的使用
demo1
A、创建一个目录
mkdir app
B、在app目录中添加main.js文件
document.write("It works。");
C、在app目录中添加index.html文件
<!DOCTYPE html> <html><head><meta charset="utf-8"><title>学习webpack</title></head><body><script type="text/javascript" src="bundle.js"></script></body> </html>
D、执行命令
webpack main.js bundle.js
E、在浏览器中打开index.html
即可看到,It works。
demo2
下面以demo1为基础,添加或修改文件。
A、在app目录中添加inner.js文件
module.exports = "It works from inner.js。";
B、更新main.js
document.write(require("./inner.js"));
C、执行命令
webpack main.js bundle.js
D、在浏览器中打开index.html
即可看到,It works from inner.js。
三、webpack的loader
Webpack本身只能处理原生的JavaScript模块,如果要处理其他类型的文件,就需要使用loader进行转换。
所以如果我们需要在项目中添加css文件,就需要使用css-loader和style-loader,css-loader会负责遍历css文件,style-loader会把原来的css代码插入页面中的一个style标签中。
1、安装css-loader
以上面的demo2为基础,在当前目录安装css-loader和style-loader
cnpm install css-loader style-loader
全局安装,需要加-g。
执行以上命令后,会在当前目录生成node_modules文件夹,它就是css-loader和style-loader的安装目录。
2、使用css-loader
首先,在app目录中添加style.css文件
body{color:red; }
其次,介绍3种使用css-loader的方法
方法A:修改main.js文件
require("!style-loader!css-loader!./style.css");
document.write(require("./inner.js"));
执行命令
webpack inner.js bundle.js
在浏览器中打开index.html
即可看到,It works from inner.js字体变红。
方法B:修改main.js文件,在执行命令的时候绑定。
require("./style.css");
document.write(require("./inner.js"));
执行命令
webpack inner.js bundle.js --module-bind 'css=style-loader!css-loader'
在浏览器中打开index.html
即可看到,It works from inner.js字体变红。
方法C:添加配置文件,把编译内容放在文件中,统一管理。
//修改main.js,有两种导入css的方式。 // import './style.css'; require('./style.css');
//在app目录中添加webpack.config.js文件 module.exports = {entry: "./main.js",output: {path: __dirname, // __dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录。filename: "bundle.js"},module: {loaders: [{ test: /\.css$/, loader: "style-loader!css-loader" }]} };
webpack.config.js文件通常放在项目的根目录中,它本身也是一个标准的Commonjs规范的模块。
接下来我们只需要执行webpack命令,即可生成bundle.js文件。
在浏览器中打开index.html
即可看到,It works from inner.js字体变红。
最后,介绍4种使用url-loader的方法
//require require("url-loader?mimetype=image/png!./file.png");//cli webpack --module-bind "png=url-loader?mimetype=image/png"//配置文件 { test: /\.png$/, loader: "url-loader?mimetype=image/png" }//配置文件 {test: /\.png$/,loader: "url-loader",query: { mimetype: "image/png" } }
四、webpack的plugins
webpack自带一些插件(内置插件),你也可以安装一些插件。
下面以BannerPlugin为例,介绍如何安装和使用内置插件。
1、安装内置插件
cnpm install webpack --save-dev
2、修改webpack.config.js文件
var webpack=require('webpack');module.exports = {entry: "./main.js",output: {path: __dirname,filename: "bundle.js"},module: {loaders: [{ test: /\.css$/, loader: "style-loader!css-loader" }]},plugins:[new webpack.BannerPlugin('尝试webpack的内置插件');] };
执行命令webpack,打开bundle.js,可以看到文件头部出现了我们指定的注释信息,BannerPlugin插件的作用就是在编译文件中的首部插入注释信息。
上面通过一个main.js入口文件,一个index.html,一个index.js,一个style.css文件,和webpack命令,帮我们生成构建后的bundle.js。
五、常用命令
1、构建一个开发目录
webpack
2、查看所有命令
webpack -h
webpack --help
3、构建一个生产目录,对打包后的文件进行压缩混淆
webpack -p
4、生成map映射文件
webpack -d
5、连续构建,监听
webpack --watch
6、美化展示信息
webpack --colors
7、找出详细的错误信息
webpack --display-error-details
8、使用webpack.config.prod.js配置文件来打包
webpack --config webpack.config.prod.js
六、开发环境
上面都是修改完文件,执行命令后,直接打开index.html,手动刷新看效果。
这里介绍的webpack-dev-server可以实现自动刷新,它是一个小型的Node.js Express静态文件服务器,使用webpack-dev-middleware来服务于webpack的包,安装及使用方法如下。
1、安装和使用
A、安装webpack-dev-server
cnpm install webpack-dev-server -g
B、在app目录中执行webpack-dev-server
webpack-dev-server
如果自动刷新,可以这么做,不要--hot。
webpack-dev-server --inline
C、在浏览器打开http://localhost:8080/
可以浏览项目中的页面和编译后的资源输出。
也可以通过命令打开浏览器,写法如下:
webpack-dev-server --open
webpack-dev-server && open http://localhost:8080 -a 'google chrome'
注意:webpack-dev-server生成的bundle.js包并没有放在真实目录中,而是放在了内存中。
2、两种模式
webpack-dev-server支持两种模式来自动刷新页面,分别是iframe模式和inline模式,这两种模式都支持热模块替换,好处是只替换更新的部分,而不是页面重载。
A、iframe模式
这种模式不用额外配置,只要按照http://localhost:8080/webpack-dev-server/index.html格式访问url即可。
B、inline模式
这种模式,url不用变化,但是需要配置。
先配置webpack.config.js文件,可以参考官网
output:{path: 'lib',publicPath: "http://127.0.0.1:8080/lib/",filename: 'bundle.js' }, devServer:{contentBase: path.join(__dirname, ""),historyApiFallback: true, //不跳转hot: true,inline: true //实时刷新 }, plugins:[new webpack.DefinePlugin({'process.env.NODE.ENV':"development"}),new webpack.HotModuleReplacementPlugin() ]
每次敲一长串命令,是不是有些麻烦呢?配置一下package.json文件即可。
"scripts": {"test": "echo \"Error: no test specified\" && exit 1","start": "webpack","server": "webpack-dev-server --open","build": "webpack-dev-server --inline" }
npm run start 替代 webpack
npm run build 替代 webpack-dev-server --inline
"scripts": {"dev": "webpack-dev-server","build": "webpack --config webpack.config.prod.js" }
运行npm run build来编译生成生产模式下的bundles;
运行npm run dev来生成开发模式下的bundles以及启动本地server。
webpack打包输出真实的文件,而webpack-dev-server开启服务输出的文件只存在于内存中,不输出真实的文件!
做过一些尝试后,你会发现webpack比较灵活,webpack.config.js和package.json对于运行项目来说,都很有用。而且,webpack.config.js文件中的参数发挥的作用等价于package.json文件中的scripts条款,如果不想在命令中拼接太多参数,可以配置webpack.config.js。
七、打包原理
在入口文件中,对每个require资源文件配置一个id。对于同一个资源,不管require多少次,它的id都是一样的,所以无论在多少个文件中require,它都只会打包一份。