慕课笔记--[课程]webpack深入与实战

一、webpack可以实现的功能

可以打包 AMD、CMD、Common、css\、coffee、json、Image 等均可打包,也可以打包自定义后缀的文件,如:.vue、.jsx 等,都可以通过loaders加载器进行处理打包。
目前webpack+react+es6 的组合非常常见。
特性:
(1)、将js、css等文件视为一个模块,将外部或者第三方文件也视为一个模块
(2)、实现按需加载,是浏览器能够在最短时间打开项目
(3)、适合大型项目操作
二、webpack的目标

(1). 其他打包工具不具备的代码分割,切分依赖库,分开加载所需的依赖,使加载速度加快。
(2). 全面的loaders加载系统
(3). 插件系统,如模块热更新
三、webpack的安装与命令行指令
信息说明:
(1)、在 webpack 2中 指定的 loader 要使用双引号 
webpack hello.js hello.bundle.js --module-bind "css=style-loader!css-loader"  //绑定css的loader
(2)、webpack -g  //查看webpack命令
(3)、css-loader使得webpack可以处理.css 文件。
style-loader将css-loader处理完的文件新建一个<style>插入到HTML里
npm install css-loader style-loader -save-dev //下载用于适配css文件的loader
(4)、npm install webpack --save-dev     //下载webpack
npm init // 在项目中引导创建一个package.json文件
安装包的信息可保持到项目的package.json文件中,以便后续的其它的项目开发或者他人合作使用,也说package.json在项目中是必不可少的。
(5)、style.loader!css.loader 意思是!前模块依赖!后模块,就是style依赖css
(6)、我想看到打包过程,可以使用--progress, 在此我们可以看到一个百分比读条
webpack hello.js hello.bundle.js --module-bind "css=style-loader!css-loader" -progress
(7)、每一次在命令行输一次命令行命令,十分的繁琐,可以使用--watch使它自动更新,自动打包。
(aSuncat: css-loader后面不要加!,mac下是单引号'',windows是双引号"")
webpack hello.js hello.bundle.js --module-bind "css=style-loader!css-loader" -watch
(8)、webpack支持的三种模块化方式:md,commonJs, es6.
require(‘.world.js’)的写法是commonJs的
(9)、webpack天生不支持css类型的文件,如果要处理这种文件,就要依赖css.loader。
而如果要在html中引入css样式需要style.loader将样式通过style标签插入到head标签中。
(10)、在使用require加载css模块时要引进style-loader(使样式以嵌入的形式插入页面)和css-loader(识别css文件):require('style-loader!css-loader!./style.css');
完整的步骤:
(1)、cd 进入一个目录
(2)、mkdir webpack-test
(3)、cd webpack-test
(4)、npm init
(5)、npm install webpack --save-dev
(6)、npm install css-loader style-loader -save-dev //下载用于适配css文件的loader
(7)、webpack hello.js hello.bundle.js --module-bind "css=style-loader!css-loader" --watch  --progress
其他参数:
--display-reasons //打包原因
--progress -dispaly-modules //列出打包模块
--progress  //查看打包过程
--watch //文件更新时自动打包
--colors: 显示颜色
打包过程中信息解析:
我们会看到hash值,webpack的版本号,打包的时间,Asset是指这次打包生成的文件,
Size是指文件的大小,Chunks是指这次打包的方块,Chunk name是指这次打包的块名称
三、建立项目的webpack配置文件(一)
1、信息说明:
(1)、webpack 命令直接默认执行 webpack.config.js 文件。如果要更改 则使用 --config  webpack --config webpack.dev.js
(2)、webpack.config.js 文件在 window的配置中webpack的 path 应该加上绝对的路径。推荐使用绝对路径,防止不同版本的冲突
var path = require("path")    //webpack2需要先引入path
module.exports = { //输出
entry: '/src/script/main.js', //指定打包的入口文件, string 单独入口 | object 多个入口多个文件 | array 多个入口合并在一个文件中
output: { //指明打包以后的文件放在什么地方
path: path.resolve(__dirname , '/dist/js/'),
filename: 'bundle.js' //指定打包以后的文件名叫什么
}}
备注1:如果你的entry是多余一个的,那么你可以使用一些占位符保证你输出的文件名是唯一的。
output的filename这些占位符有三个
[name]表示chunk的的name,也就是chunk的key
[hash] 是每次打包的hash
[chunkhash] 每个模块自己的hash值,可以理解为版本号,也理解为md5值(保证每个文件的唯一性)
备注2:entry入口文件有三种定义方式:
# 单独定义一个文件
# 将两个或多个平行文件定义在一个数组中,它们会被打包为一个文件
# 将两个或多个文件定义在一个对象中,它们会被分别打包
(3)、如果是webpack.config.js改名字,改成webpack.dev.config.js
终端目标文件输入:webpack会失效
终端目标文件输入:webpack --config webpack.dev.config.js会生效
(4)、package.json中的scripts中写入webpack的参数后,
eg:  "webpack":"webpack --config web pack.config.js  --color --progress "
终端目标文件输入:npm run webpack
(5)、 js文件中如果要引入css等其他文件,需要使用loader,有三种引用方式:
# 直接在引入文件路径前加loader名称,例如:require('style-loader!css-loader!./style.css'); 
#在命令行里加:webpack entry.js bundle.js --module-bind 'css=style-loader!css-loader';
# 在配置文件中加:
loaders: [{
test: /\.css$/,
loader: 'style-loader!css-loader'
}]
四、webpack配置文件(二)
1、针对多页面应用
entry使用一个对象 {
path1: ‘./script/main.js’,
a: ‘./script/a.js’
},
output: {
path: ‘./dist/js’,
filename: ‘[name].[hash].js’
// [name] path1 和 a ,[hash] 本地打包的md5值 没有修改的部分hash值不会改变,起到增量修改,不重新加载浏览器缓存过的没有修改文件
}
2、entry
三种输入方式
(1)string,输入字符串
    entry:{
        main:'./src/script/main.js'
    },
(2)array, 数组。适用情况:两个平行的,不相依赖的文件打包在一起。
    entry:{
        main:['./src/script/main.js','./src/script/a.js']
    },
(3)object, 适用情况:多页面应用程序。这里要和output里的[name]占位符配合使用,威力才能最大。如果你要打包成多个js文件,那么entry对象里的key叫做chunk就是文件名,里面的值就是需要打包的文件里面包含的文件。
    entry:{
        main:'./src/script/main.js',
        a:'./src/script/a.js'
    },
3、output
占位符有3种:[name]、[hash]、[chunkhash]
output的filename
(1)hash: 这次打包的hash
每次终端运行webpack命令,都会生成一段信息,这段信息的第一行就有一个hash
(2)chunkhash:每一个chunk自己的hash
五、自动化生成项目中的html页面(一)
针对每次修改js文件之后,[hash]占位符就会改变,在index.html引用中,每次都要更改文件名的繁琐工作,可以利用插件解决:
1. 命令窗口输入:npm install html-webpack-plugin --save-dev
2. 在配置文件webpack.config.js中引用插件(commonjs模块写法):var htmlWebpackPlugin = require('html-webpack-plugin');
3. 在插件属性中初始化plugin:
module.exports = {
    plugins:[
        new htmlWebpackPlugin()
    ]
}
这里的代码只会让webpack自动生成一个index.html,里面自动把js代码插入到index.html当中。//注意,这里说的是webpack生成的index.html,不是你自定义的index.html。
4. 再打包一次:在命令窗口输入npm webpack run
5. 生成的index.html文件就能自动引用之前生成的两个js文件
6. 让两个ndex.html建立联系:在plugins的设置中加入模板参数:
module.exports = {
    plugins:[
        new htmlWebpackPlugin({
                template: 'index.html' //此时上下文环境默认在根目录下,是你自己写的文件
       })
    ]
}
7. 让生成的js和html文件放在不同的文件夹下:修改output参数
   output:{
        path: path.resolve(__dirname, 'dist'),   //打包后的存放路径
        filename:'js/[name]-[chunkhash].js',   //增加一个相对路径
	publicPath:'http://cdn.com'                //设置上线地址
    },
8. 插件的其它参数:
plugins:[
        new htmlWebpackPlugin({
            filename:'index-[hash].html',  //文件名
            template:'index.html',  //传参,让两个html文件建立联系
            inject:'head',  //让生成的script标签放在head标签还是body标签中
	    title: 'i am back',  //html中的title要取到这个值,需要写成:<title><%= htmlWebpackPlugin.options.title %></title>
	    date: new Date(),   //html中的date要取到这个值,需要写成:<div><%= htmlWebpackPlugin.options.date %></div>
	    chunks: [ ' main', ' '],	// 可以用于htmlWebpackPlugin.files.chunks[’main’].entry 就可以拿到chunk main生成的文件名称
	    excludeChunks: [' ', ' '],	//排除那些chunk在html模板中被拿到
	    minify: {     //压缩当前生成的html文件, 在plugins中添加minify属性
  	         removeComments:true       //删除注视
	         collapseWhitespace: true   //删除空格
	    }   
        })
    ]
五、自动化生成项目中的html页面(二)
1、参数中传参,模板中引用
config中的title设置,然后对index.html中用<%= %>进行取值
<%= %>表示:需要对什么进行取值
一般引用htmlWebpackPlugin里的值,直接htmlWebpackPlugin.options.title。
2、index.html中遍历:
<!--遍历:得到的htmlWebpackPlugin的key是files和options,再分别对这两个key进行遍历-->
    <% for (var key in htmlWebpackPlugin.files){ %>
        <%= key %>:<%= JSON.stringify(htmlWebpackPlugin.files[key]) %>
    <% } %>
    <% for (var key in htmlWebpackPlugin.options){ %>
        <%= key %>:<%= JSON.stringify(htmlWebpackPlugin.options[key]) %>
    <% } %>
注:JSON.stringify(htmlWebpackPlugin.files[key])对这一对象的内容字符串化
3、htmlWebpackPlugin.files.chunks[’main’].entry 就可以拿到chunk main生成的文件名称。
4、https://www.npmjs.com中搜索html-webpack-plugin可以看到对插件的详细解释
5、path:输出的时候把所有文件都放到合格目录下, 设置上线地址:在output中添加publicPath属性.
publicPath:占位符,需要上线,设置时,如果设置为http://cdn.com,这样js的路径就会替换为绝对地址以http://cdn.com开头的路径,这样就能满足上线需求了。
6、压缩当前生成的html文件:在plugins中添加minify属性
https://www.npmjs.com,输入html-webpack-plugin,然后搜索minify,找到html-minify的链接点进去,能看到minify的参数列表。
(1).  removeComments:true   //删除注视
(2). collapseWhitespace: true   //删除空格
7、完整index.html ejs模板
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title><%= htmlWebpackPlugin.options.title %></title>
  //在模板文件中获取webpack中entry的路径的
  <script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks.main.entry %>">
  </script>
  <script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks.a.entry %>">
  </script>
</head>
<body>
  <%= htmlWebpackPlugin.options.date%>
  <!--<% for(var key in htmlWebpackPlugin.files){%>
    <%= key%> : <%= JSON.stringify(htmlWebpackPlugin.files[key])%>
  <%}%>
  <% for(var key in htmlWebpackPlugin.options){%>
    <%= key%> : <%= JSON.stringify(htmlWebpackPlugin.options[key])%>
  <%}%>-->
</body>
</html>
六、自动化生成项目中的html页面(三)
1、多页面如何引用属于自己的js文件,可以借助htmlwebpackplugin配置chunks
2、如果想用不同的模版生成不同的html文件,只用在plugins里添加各种htmlWebpackPlugin的实例就好了。
3、页面中引入inline的script
github上,ampedandwired/html-webpack-plugin/examples/inline/template.jade中可以看到代码。
4、htmlWebpackPlugin.files.chunks.entry就是chunks输出的地址
5、main以inline的形式引进,a,b,c以外链的形式引进
6、index.html中
(1)在htmlWebpackPlugin的配置中有一个有一个参数chunks可以配置。
(2)head中
<script type="text/javascript">
        <%= compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %>
</script>
重点:!!!compilation.assets是webpack暴露出来可以获取文件数据的方法。通过传文件名路径进这个对象,拿到这个文件的索引,通过调用source拿到文件内容。
compilation.assets需要的是不带publicPath,htmlWebpackPlugin.files.chunks.main.entry带publicPatch,所以用substr()截取。
(3)body中
    <% for (var k in htmlWebpackPlugin.files.chunks){ %>
        <% if(k!='main') %>
            <script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks[k].entry %>"></script>
        <% } %>
    <% } %>
(4)config.js中inject为false
7、小结
(1)、html和动态生成的文件一一对应。
(2)、htmlWebpackPlugin,如何自定义html,并且通过模板,参数如何传参。
(3)、多页面时,如何通过htmlWebpackPlugin生成多个html
(4)、深入探究通过htmlWebpackPlugin,结合模板的方式把生成的js,通过inline引入到html中
8、完整index.html  ejs模板
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title><%= htmlWebpackPlugin.options.title %></title>
  //在模板文件中获取webpack中entry的路径的
  <script type="text/javascript" src="<%= compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %>">
  </script>
</head>
<body>
<% for (var k in htmlWebpackPlugin.files.chunks){ %>
        <% if(k!='main') %>
            <script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks[k].entry %>"></script>
        <% } %>
<% } %>
</body>
</html>
七、什么是 Loader 以及 Loader 的特性 
1、新建一个组件(component),layer有自己的模版文件和css文件还有js文件。然后用export default导出去可以给别人调用。这都是es6的写法。
2、loader可以生成额外的文件.
(外注:Webpack 本身只能处理原生的 JavaScript 模块,但是 loader 转换器可以将各种类型的资源转换成 JavaScript 模块。这样,任何资源都可以成为 Webpack 可以处理的模块。)
3、进入webpack网站的user loaders:
使用loader的三种方式
(1)、require的路径前面加loader!
(2)、直接配置配置文件
loaders
test:对资源的正则匹配,如果匹配到Loader,就会对其进行处理。
(3)、直接使用cli
webpack --module-bind jade --module-bind 'css=style!css',指定了2个loader,先是css loader,然后是style loader
八、使用 babel-loader 转换 ES6 代码(上)
1、babel
(1)、babel是一个转换编译器,它能将ES6转换成可以在浏览器中运行的代码
(2)、安装babel
终端目标文件夹输入:npm install --save-dev babel-loader babel-core
(3)、loader:'babel-loader'可以正常运行,视频中的loader:'babel'不能正常运行。
(4)、babel的loader是一个非常耗时的转换。
改善之前的时间是8260ms
2、改善:
(1)webpack 的api的configuration
loaders的参数5个:test,exclude,include,loader,loaders
(2)改善方法:exclude,include参数
例如:exclude:'./node_modules/',//node_modules是已经引用过的,已经打包过的文件,其实这里对速度没有影响,这是告诉你如果是不相关的文件,可以用exclude
include:'./src/',
1)会报错:-configuration.module.loaders[0].exclude: The provided value "./node_modules/" is not an absolute path!
2)报错的解决方法:
    exclude:__dirname+'/node_modules/',//已经引用过的,已经打包过的文件
    include:__dirname+'/src/',
(3)这样初步改善后时间是1210ms
3、完整配置代码
// nodeJS原生的path方法,使用require引入
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    context: __dirname,
    entry: {
    	main: './src/app.js'
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'js/[name].bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: path.resolve(__dirname, '/node_modules/'),
                include: path.resolve(__dirname, '/src/'),
                options: {
                    presets: ['env']
                }
            },
            {
                test: /\.css$/,
                use: [
                'style-loader',
                {
                  loader:'css-loader',
                  options: {importLoaders:1}
                },
                 'postcss-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                'style-loader',
                {
                  loader:'css-loader',
                  options: {importLoaders:1}
                },
                 'postcss-loader',
                 'less-loader'
                ]
            },
            {
                test: /\.scss$/,
                use: [
                'style-loader',
                {
                  loader:'css-loader',
                  options: {importLoaders:1}
                },
                 'postcss-loader',
                 'sass-loader'
                ]
            },
            {
                test: /\.html$/,
                use: [
                'html-loader'
                ]
            },
            {
                test: /\.tpl$/,
                use: [
                'ejs-loader'
                ]
            },
            {
              // 加入file-loader处理图片文件
              test: /\.(png|jpg|jpeg|gif|svg)$/i,
              use: [
                {
                  // loader: 'file-loader',
                  loader: 'url-loader',
                  options: {
                    limit: 10000,
                    name: 'assets/[name]-[hash:6].[ext]'
                  }
                }
              ]
            }
        ]
    },
    plugins: [
    	new htmlWebpackPlugin({
    		filename: 'index.html',
    		template: 'index.html',
    		inject: 'body'
        })
    ]
}
 

九、处理项目中的 css

1、安装style-loader和css-loader
终端目标文件输入:npm i style-loader css-loader --save-dev
2、webpack可以将任何资源视为一个模块。
3、这里将css引用进来,
(1)、app.js:用的是es6的import语法
(2)、webpack.config.js: module的loaders
4、postcss-loader
对css进行浏览器兼容性考虑时,可以用到这个loader
(1)、安装postcss-loader
终端目标文件输入:npm install postcss-loader --save-dev
(2)、是一个后处理器。
(3)、可以加浏览器的前缀
5、安装autoprefixer
终端目标文件输入:npm install autoprefixer --save-dev
(1)、loader处理方式是从右到左,即从数组的最后一项往前
(2)、webpack.config.js中,
视频中的配置现在的postcss已经不支持了,我的配置是

十、关于postcss-loader问题的有效解决方案:

1、在webpack.config.js同级目录下 创建 postcss.config.js
(1)postcss.config.js 代码如下
module.exports = {
    plugins:[
        require('autoprefixer')({ browsers: ["last 5 versions"]})
    ]
(2) webpack.config.js 代码如下

    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    'babel-loader'
                ]
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader'
                ]
            }
        ]
    }

2、webpack 2.4配置postcss-loader


module:{
rules:[
{
test:/\.js$/,
loader:'babel-loader',
exclude:path.resolve(__dirname+"/node_modules/"),
include:path.resolve(__dirname+"/src/"),
query:{
presets:'latest'
}
},
{
test:/\.css$/,
use:[
'style-loader',
{loader:'css-loader',options:{importLoaders:1}},
{
loader:'postcss-loader',
options:{
plugins:function(){
return [
require("autoprefixer")({browsers:['last 5 versions']})
]
}
}
}
]
}
]
}

十一、处理项目中的less与sass

1、less-loader
(1)、安装:
终端目标文件输入:npm i less-loader --save-dev
错误提示:npm WARN less-loader@4.0.3 requires a peer of less@^2.3.1 but none was installed.
说明less没有装
(2)、安装less
终端目标文件输入:npm i less --save-dev
2、less-loader
基本配置是 loader: ‘style-lander!css-loader!postcss-loader!less-loader’
3、sass-loader
(1)、安装
终端目标文件输入:npm i sass-loader --save-dev
出现错误提示:
npm WARN sass-loader@6.0.3 requires a peer of node-sass@^4.0.0 but none was installed.
说明需要安装node-sass,解决方法:
终端目标文件输入:npm i node-sass -g --save-dev

十二、处理模板

1、layer.html是模板文件
处理模板文件的做法:

(1)webpack将模板文件当做一个字符串进行处理。

(2)webpack将模板文件当成已经编译好的的模板的处理函数。
对js模板语法,模板引擎,模板的作用的认识和了解再来看这章会比较容易理解。
2、要支持html文件,安装html-loader
终端目标文件输入:npm install html-loader --save-dev
3、要支持.ejs文件或者是.tpl文件,安装ejs
终端目标文件输入:npm install ejs-loader --save-dev
layer.js载入ejs模板时,返回的是一个function,这时的import tpl from './layer.tpl';中的tpl代表的不再是字符串,表示的是一个已经编译过的函数
4、react——jsx
       vue——jsx

十三、处理图片及其他文件

##、添加图片
1、css中的背景图片。
(1)安装file-loader
终端目标文件输入:npm install file-loader --save-dev
2、模板文件layer.tpl直接引用图片。
(1)绝对路径:直接写绝对路径就行。
(2)相对路径:    <img src="${require('../../assets/bg.jpg')}"
3、最根部的文件index.html引用图片。
(1)绝对路径:直接写绝对路径就行。
(2)相对路径:file-loader
##、图片打包后的输出地址:
 1、       query:{
                  name:'assets/[name]-[hash:5].[ext]'
              }
2、安装url-loader
url-loader和file-loader相似,但是url-loader可以指定limit参数。
(1)终端目标文件输入:npm install url-loader --save-dev
url-loader可以处理文件或者图片,当文件/图片大小大于指定的limit,就会丢给filel-loader去处理,当小于设定的limit,就会转为base64编码,不再是一个url(不再是一个http请求),图片会被打包进html,css,js
(2)两种图片引用方式:①通过http请求load进来。浏览器会有缓存,比较适用于重复性较高的图片。②打包成base64。任何地方要用时,都会有base64编码存在那里,会造成代码的冗余,增加代码的体积。
##、压缩图片
1、安装image-webpack-loader
终端目标文件输入:npm install image-webpack-loader --save-dev
2、先压缩文件再传给url-loader判断。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值