webpackの学习笔记2
code spliting 代码分割 可以选择加载项目当时只需要的文件
loader 模块是通过loader处理各种各样的文件,如js文件、css文件、图片
模块的打包器
安装webpack
mkdir webpack-test //建立webpack-test文件夹
cd webpack-test //进入webpack-test文件夹
npm init //npm初始化
npm install webpack –save-dev //在当前文件夹下安装webpack
webpack hello.js hello.bundle.js //js打包,利用webpack将hello.js打包为hello.bundle.js
asset:该次打包对应生成的文件
size:打包文件的大小
chunks:该次打包的分块
chunk Names:块名称
将多个js文件打包在一个js文件里,newhell为打包后的js文件:
webpack自身不支持css文件打包,处理这种文件需要下载相关的css依赖。
npm install css-loader //在相应的项目文件下安装css-loader
npm install css-loader style-loader –save-dev
打包css文件,相应的css文件可被打包进newhell.js文件中了:
css-loader使得webpack可以处理css类型的文件,style-loader把css-loader处理完的文件新建一个标签,插入到当前html文件里。当当前html文件引入打包后的文件后,该段代码就会被执行,而所写的css样式就会被插入到当前html的head标签里。
如果css文件过多的情况下每次都引入css-loader、style-loader就比较麻烦,这个问题,我们可以在命令行下进行解决。
webpack hell.js newhell.js –module-bind ‘css=style-loader!css-loader’
如果是css文件将其绑定到style-loader,css-loader
相应的书写js文件中只需要引入require(’./style.css’)即可。
输入webpack –h可以查看webpack的帮助文档,查看一些命令参数
webpack hell.js newhell.js --module-bind "css=style-loader!css-loader" --watch
其中,watch参数,可用来进行监控,当文件发生改变时,进行自动更新自动打包。
Ctrl+C可退出当前命令。
webpack hell.js newhell.js --module-bind "css=style-loader!css-loader" --progress
其中,progress参数,可以看到打包过程
webpack hell.js newhell.js --module-bind "css=style-loader!css-loader" --progress --display-modules
查看打包模块
webpack hell.js newhell.js --module-bind "css=style-loader!css-loader" --progress --display-modules –display-reasons
打包相应模块的原因
建立项目的webpack配置文件:
C:\Users\DELL>d:
d:\>mkdir test6
d:\>cd test6
d:\test6>mkdir webpack-demo1
d:\test6>cd webpack-demo1
d:\test6\webpack-demo1>npm install webpack --save-dev
//在该项目目录下安装webpack
d:\test6\webpack-demo1>mkdir src
d:\test6\webpack-demo1>mkdir dist
webstorm打开该项目,建立inde.html、script、style、webpack.config.js等文件。
webpack的简单配置:
var path=require("path"); module.exports={ entry:'.src/script/main.js', /*打包的入口文件*/ output:{ /*指明打包以后的文件放在什么地方*/ path:path.resolve(__dirname+'/dist/js'), /*打包以后的文件路径*/ filename:'bundle.js' /*打包以后的文件名*/ } }
这里卡了很久啊,上面版本的代码总是提示不是绝对路径,可就算用了绝对路径也是不行,百度了那么久也没找到答案。。。还好有万能的讨论区。。。原来是版本不匹配问题。。。
配置文件名为webpack.config.js,可直接在命令行输入:webpack
如果配置文件名为webpack.dev.config.js,则在命令行输入:webpack webpack.dev.config.js
webpack在命令行中使用的一些参数,如何加这些参数呢?这可以配合着npm的一些脚本实现。在package.json中的scripts属性处可定义一段脚本,脚本的内容为真实的webpack的命令。即"webpack":"webpack --config webpack.config.js --progress --display-modules --colors --display-reasons"
然后只需要在命令行运行:npm run webpack,会直接运行我们之前在package.json的scripts属性中预先写好的脚本。
Webpack配置的empty和output:
empty入口文件有三种形式:字符串、数组、对象
入口为字符串形式:
入口为数组形式:
入口为对象形式:
Ps:当入口为对象形式时,可能会有多个块chunk,如main、a,那么当打包时就会生成对应个数的打包文件bundle.js,这时就会产生覆盖。为了避免覆盖,不同的chunk生成各自对应的打包文件,则需要在output处做修改,将其打包后的命名方式改变,可以通过[name]或[hash]或[chunkhash]进行占位,生成对应的打包文件名,如下:
自动生成项目中的html页面:
Index.html页面中需要引入打包后的js文件,那么如果打包后的js文件名不固定该怎么办呢?这里可以通过webpack插件html-webpack-plugin进行解决。先在命令行下载该插件:npm install html-webpack-plugin –save-dev。–save-dev可以实现自动更新package.json文件。然后在webpack.config.js配置文件中建立对该插件的引用:
var htmlWebpackPlugin=require('html-webpack-plugin');
同时,需要添加Plugins属性
运行npm run webpack,
将在js文件夹(与打包后文件同一文件夹)下生成独立的index.html,该文件中会自动引入打包后名字不固定的打包js文件。但这里生成的index.html文件与我们一开始自己写的index.html文件没有建立联系。
自动生成的index.html文件:
自定义的index.html文件:
那么该如何建立它们之间的联系呢?或者是否可以让自动生成的html文件以我们一开始自己定义的文件为模板自动生成呢?
我们可以给插件进行传参,传入的参数本质上是一个对象。为其传入一个模板,即为我们自定义的index.html。如下:
这里为cpm run webpack运行结果:
这里为自动生成的index.html文件:
这样的话,我们自定义的模板文件index.html就不用指定script标签引入打包后的js文件了。
这里还有一个问题:自动生成的index.html文件在js目录里,这与我们实际开发不符。这是因为我们的output中定义输出的路径path即为相应的js文件夹。我们需要修改一下output中的属性设置,如下:
运行npm run webpack ,即可得到我们想要的状态,即js目录下为打包后的js文件,index.html在外面:
配置文件中插件plugins属性也可以指定我们生成的html文件的名称:
运行npm run webpack:
还可以在plugins中指定我们生成的脚本是放在head标签里还是放在body标签里
运行npm run webpack,打开自动生成的html文件,则可看到自动生成的js文件引入在了head标签里:
接着提出新的需求:在参数中传参,在模板中引入?如我们在plugins参数中传入title属性及其值,希望通过模板能够直接获取到传入的title参数及值。
我们在plugins中添加title属性及其值,然后在模板index.html中引入该参数,<title><%=htmlWebpackPlugin.options.title%></title>
运行npm run webpack,得到生成的html文件,可以看到title参数值自动加载进来了:
Plugins中添加其他参数值也是可以实现的,如:
运行npm run webpack,查看生成的html文件:
还有一个问题:我们每次运行一次脚本npm run webpack,就会对应生成一个html文件,当脚本运行次数多了,就会产生很多html文件,这样会给我们造成混乱,且不易辨别哪个html文件是刚生成的。这里直接将plugins中的filename:'index-[hash].html',改为filename:'index.html',即可。这样每次生成的文件都以index.html命名,将会覆盖掉前面生成的同名文件。
Ps:在模板文件中直接取值用<%= %>; 在模板中直接运行json代码用<% %>
运行npm run webpack,查看生成html文件,可看到htmlWebpackPlugin的属性有files、options
遍历htmlWebpackPlugin的file及options:
运行npm run webpack,得到对应的chunk、js、css文件、所有插件的参数值,打包以后的key与value:
增加新的需求:我们想把一部分生成的js放在head标签里,一部分生成的js放在body标签里。这里需要改变自定义的index.html文件。因为该文件可以直接引用打包生成之后的信息,所以我们可以直接通过script标签引入。比如我们把main.js生成的js放在head标签里,把a.js生成的js放在body标签里。这时,我们需要将配置文件中的inject属性值设置为false,同时在自定义模板index.html文件中head和body标签处放置相应的script标签:
运行npm run webpack,即可看到生成的html文件按照我们的要求将打包后的js文件放在相应的位置上了:
当我们打包完后项目需要上线,那么上线的地址与我们本地的地址肯定是不一样的,这时我们需要借助output的publicPath属性实现。publicPath可以理解为占位符,publicPath:'http://cdn.com/'。运行npm run webpack之后,生成的html文件中引入的js文件的位置即为加上http://cdn.com/的绝对地址,可理解为线上地址:
上线的话,需要对进行压缩,可以在plugins中的minity属性对生成的html文件进行压缩:
运行npm run webpack,发现生成的html文件中的注释和空格都没了:
多页面应用:
多个页面对应着需要自动生成多个html文件,这里借助htmlWebpackPlugin插件可以实现。
给设置生成的chunk进行html插件的调用:
运行npm run webpack,得到对应的3个html文件:
上面同一个模板的情况下会造成引入的chunks是一样的,从而导致引入的打包后的js文件是相同的,这与实际需求有出入。为了解决这个问题,可以在配置文件的plugins中添加chunks参数,它是一个数组,不同的chunk对应生成不同的打包js文件。同时将其中的inject参数值改为body,将对应生成的js文件注入到body标签里。
运行npm run webpack,abc三个html页面中引入了对应的打包后的js文件:
当entry处有更加多的选择,chunks过多,必须为每个html指定它的chunks,且若它的chunks包含我们之前指定的chunks的绝大多数,若依次为生成的html文件指定chunk,将会非常繁琐。这时htmlWebpackPlugin插件为我们提供了一个参数excludeChunks,表示除了哪些chunks被排除之外:
运行npm run webpack:
如果希望页面的内容得到极致,把一些初始化的脚本直接切入页面(inline方式),而不以链接的形式引入到页面(会增加http请求),会提高页面速度和脚本速度,这里需要修改模板index.html和配置文件中的inject参数:
运行npm run webpack:
Webpack处理项目资源中的文件:
loader:用于对模块的源代码进行转换。Loader可以将文件从不同的语言转换为JavaScript,或将内联图像转换为data URL。
应用程序中loader使用的三种方法:
(1) 通过配置
通过webpack.config.js。module.rules允许在webpack配置中指定几个loader。如:
module:{ rules:[ { test:/\.css/, use:[ {loader:’style-loader’}, {loader:’css-loader’, options:{ modules:true } } ] } ] }
(2) 在require语句中显示使用
可以在require语句中指定loader,使用!将资源中的loader分开,分开的每个部分相对于当前目录解析。如:
require(‘style-loader!css-loader?modules!./style.css’);
(3) 通过CLI
使用babel-loader转换es6代码:
npm install --save-dev babel-loader babel-core
//安装babel-loader和babel-core
npm install --save-dev babel-preset-latest(1.x)
npm install --save-dev babel-loader babel-core babel-preset-env webpack(2.x)
//安装babel-preset-env
两种方式指定:
(1)webpack.config.js中设置
module:{ loaders:[ test:/\.js$/, loader:'babel-loader', options:{ presets:['env'] } ] }
(2)package.json中配置
“babel”:{ “presets”:["env"] }