webpack是一个module bundler(模块打包工具),所谓的模块就是在平时的前端开发中,用到一些静态资源,如JavaScript、CSS、图片等文件,webpack就将这些静态资源文件称之为模块。
它在很多地方都能替代Grunt和Gulp,因为它能够编译打包CSS,做CSS预处理,对JS的方言进行编译,打包图片,代码压缩等等。所以在我接触了gulp之后,就不太想用gulp了。
在自己的学习使用中、和技术交流群里以及和朋友的讨论、网上其他大神的博客中得到一些为什么要使用webpack的原因,webpack的优点,webpack更适用于哪里。
对 CommonJS 、AMD 、ES6的语法做了兼容;
对js、css、图片等资源文件都支持打包;
串联式 模块加载器 以及 插件机制 ,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、ES6的支持;
有独立的配置文件webpack.config.js;
可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间;
支持 SourceUrls 和 SourceMaps,易于调试;
具有强大的Plugin接口,大多是内部插件,使用起来比较灵活;
webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快;
webpack最常用与spa应用,主要是vue和React,其实它就非常像Browserify,但是将应用打包为多个文件。如果单页面应用有多个页面,那么用户只从下载对应页面的代码. 当他么访问到另一个页面, 他们不需要重新下载通用的代码。
webpack也能用于服务端,但是 构建后端代码一般都不会用webpack ,坑太多了,所以正常情况下只用于前端
没有安装node.js可以去node.js官网下载并安装(http://nodejs.cn/)。非常简单,这里不再赘述。
1. windows+R 输入cmd打开控制台,进入D盘(命令 d:)
2. mkdir webpack-test // 新建一个文件夹目录
3. cd webpack-test //进入目录中
4. npm init //初始化项目
5. npm install [email protected] --save-dev //在文件夹下装webpack(npm命令可选择用cnpm淘宝镜像,此处webpack安装版本为3.3.0)
6. atom ./ //在编辑器打开当前目录(此处为atom编辑器)
7. 打包js文件:(编辑器操作)新建一个hello.js
function hello(str){
console.log(str);
}
webpack hello.js hello.bundle.js //将hello.js打包为hello.bundle.js (安装一个webpack-cli)
webpack hello.js hello.bundle.js //运行结果:
在 js文件中引用其他js文件
require('./world.js');
8. 打包css文件:(编辑器操作)新建一个hello.css
在js中引入js和css文件
cnpm install css-loader style-loader --save-dev //安装css-loader style-loader (webpack本身不支持css类型)
require('style-loader!css-loader!./hello.css') //或者命令行:webpack hello.js hello.bundle.js --module-bind'css=style-loader!css-loader'
function hello(str){
console.log(str);
}
hello('hello world!');
webpack hello.js hello.bundle.js //运行结果:
#打包显示进度条
webpack hello.js hello.bundle.js --progress
#监听
webpack hello.js hello.bundle.js --watch
#打包模块
webpack hello.js hello.bundle.js --display-modules
#打包原因
webpack hello.js hello.bundle.js --display-reasons
9. 在项目中引入打包后文件
index.html
//src引入的是打包后的文件名
mkdir src //建源文件目录
mkdir dist //建生成静态资源目录
新建webpack.config.js文件,配置如下,index.html文件引用bundle.js
webpack //运行生成bundle.js文件
package.json文件修改:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"webpack": "webpack --config webpack.config.js --progress --display-modules --colors --display-reasons"
},
npm run webpack //运行
entry:
if you pass a string OR if you pass an array(1.打包另个不相依赖平行的js2.主js里引用多个依赖的js)
entry:["./entry1","entry2"] //只生成一个bundle文件
output : {
path:path.resolve(__dirname,'./dist'),
filename:'js/bundle.js',
}
if you pass an object(打包多个页面)
entry:["./entry1","entry2"] //生成多个带chunkhash的bundle文件,chunkhash多为版本号
output:{
path:path.resolve(__dirname,'./dist'),
filename:'js/[name]-[chunkhash]-bundle.js',
}
index文件需修改bundle文件名引用,所以需HtmlWebpackPlugin插件
HtmlWebpackPlugin 插件来帮助我们生成项目中的页面文件,通过插件的参数,配置来控制页面引入的资源,参数等。
npm install html-webpack-plugin --save-dev //安装HtmlWebpackPlugin插件
webpack.config.js文件操作
const htmlWebpackPlugin = require('html-webpack-plugin');
plugins:[
new htmlWebpackPlugin({
// filename:'index-[hash].html', //带版本号的index
filename:'index.html',
template:'index.html', //以index为模板生成静态文件
inject:'body', //指定存放位置
title:'webpack is good',
// data:new Date(),
// minify:{ //上线对js进行压缩
// removeComments:true, //删除注释
// collapseWhitespace:true, //删除空格
// }
})
]
#index模板获取到plugins.title的参数:
index文件修改:
<%= htmlWebpackPlugin.options.title %> //模板语言ejs语法
#index模板获取到plugins.data的参数
index文件修改:
<%= htmlWebpackPlugin.options.data %>
#可查看plugin的内容:
index文件修改:
<% for (var key in htmlWebpackPlugin.files) { %>
<%= key %> : <%= JSON.stringify(htmlWebpackPlugin.files[key]) %>
<% } %>
#解决3.3打包多个页面index文件需修改bundle文件名引用
index文件修改:
output : {
path:path.resolve(__dirname,'./dist'),
filename:'js/bundle.js',
publicPath:'http://cdn.com/' //打包路径
},
npm install --save-dev babel-loader babel-core //安装支持ES6语法转换
project:
layer文件:
app.js文件配置:
import layer from './components/layer/layer.js';
const App = function (){
console.log(layer);
}
new App();
webpack.config.js文件配置:
module :{
loaders:[
{
test:/\.js$/,
loader:'babel-loader'
}
]
},
npm install --save-dev babel-preset-env //安装babel-preset-env
文件根目录创建一个.babelrc文件
{
"presets": ["env"]
}
npm run webpack //运行
打开dist目录下的index文件在浏览器中
#优化打包时间:
{
test:/\.js$/,
loader:'babel-loader',
include:path.resolve(__dirname +'src'), //打包范围
exclude:path.resolve(__dirname +'node_modules') //打包过后无需再打包,绝对路径
}
npm install style-loader css-loader --save-dev //安装style-loader css-loader
在src目录下新建一个style子目录,新建一个common.css文件
html,body{ padding:0; margin: 0; background: #fff;}
在app.js文件下引用common.css文件
import './style/common.css';
#支持特殊属性:
npm install postcss-loader --save-dev //安装css后处理postcss-loader
npm install autoprefixer --save-dev //安装加浏览器前缀的处理
webpack.config.js文件配置:
{
test:/\.css$/,
loader:'style-loader!css-loader!postcss-loader' //!将两个串联,style-loader在index页面创建style标签,loaders处理方式从右向左
}
根目录新建postcss.config.js文件,配置如下:
module.exports={
plugins:[
require('autoprefixer')({
browsers:['last 5 versions']
})
]
}
npm run webpack //运行
#import引入的css文件处理
project:
webpack.config.js文件配置:
{
test:/\.css$/,
loader:'style-loader!css-loader?importLoaders=1!postcss-loader'
}
#less
npm install less-loader --save-dev //安装less-loader
npm install less --save-dev //安装less
webpack.config.js文件配置:
{
test:/\.less$/,
loader:'style-loader!css-loader!postcss-loader!less-loader'
}
#scss
npm install scss-loader --save-dev //安装scss-loader
npm install scss --save-dev //安装scss
webpack.config.js文件配置:
{
test:/\.scss$/,
loader:'style-loader!css-loader!postcss-loader!sass-loader'
}
app.js调用:
import './css/common.css';
import Layer from './components/layer/layer.js';
const App = function(){
var dom = document.getElementById('app');
var layer = new Layer();
dom.innerHTML = layer.tpl({
name:'join',
arr:['apple','xiaomi','oppo']
});
}
new App()
npm install html-olader --save-dev //安装html-olader
webpack.config.js文件配置:
{
test:/\.html$/,
loader:'html-loader'
}
#模板语法引入
例:ejs文件
layer文件夹下新建layer.ejs文件
This is <%= name %> layer
<% for(var i = 0; i < arr.length; i++){ %>
<%= arr[i] %>
<% } %>
layer.js文件引入
import tpl from './layer.ejs';
npm install ejs-loader --save-dev //安装ejs-loader
webpack.config.js文件配置:
{
test:/\.ejs$/,
loader:'ejs-loader'
},
npm install file-loader --save-dev //安装file-loader
webpack.config.js文件配置:
{
test:/\.(png|jpg|gif|svg)$/i,
loader:'file-loader'
}
1.绝对地址可直接引用
2.相对地址可用过require方式引入
webpack.config.js文件配置:
{
test:/\.(png|jpg|gif)$/i,
loader:'file-loader',
query:{
name:'images/[name]-[hash:5].[ext]' //重命名
}
}
npm install url-loader -save-dev
webpack.config.js文件配置:{
test:/\.(png|jpg|gif)$/i,
loader:'url-loader',
query:{
limit:20000,
name:'images/[name]-[hash:5].[ext]' //重命名
}
}
npm install image-webpack-loader --save-dev
webpack.config.js文件配置:
{
test:/\.(png|jpg|gif)$/i,
loaders:[
'url-loader?limit=20000&name=images/[name]-[hash:5].[ext]',
'image-webpack'
]
}