打包初体验
新建文件夹webpack-exam,组织和建立文件如下:
其中a.js
、
b.js
、
c.js
内容分别如下:
在文件夹下新建文件
webpack.config.js
,在文件中写配置:
目前浏览器并不能自动执行模块化代码,所以需要
进行webpack的配置:打开终端,切换到文件夹所在目录内层,然后执行命令
npm init -y
,在文件夹中就会默认生成一个
package.json
,里面的配置参数均为默认,自己可以根据情况进行修改:
然后执行命令
npm i -D webpack
,然后多了一个
node_modules
文件夹,里面都是相关依赖。在文件
package.json
中,在
scripts
中添加命令
dev: "webpack"
,然后在终端中输入命令
npm run dev
,控制台会进行webpack的打包和输出相关文件信息:
此时,dist文件夹就会多一个app.js,里面就是webpack打包后整合到一起的js代码。将src的index.html拷贝一份到dist目录中,然后引入dist目录的app.js(
<script src=“./app.js”></script>
),打开这个拷贝的index.html,在控制台中就可以看到打印的三句话:“this is a this is b this is c”。
如果给
webpack.config.js
改名,比如重命名为helloworld.js
,那么就该在package.json
的scripts
中将dev
的值改为webpack —config helloworld.js
(那是两个横杠),然后重新打包测试,也是成功的。
安装webpack指定版本:eg:
npm i -D webpack@3.10.0
插件
还是上面的文件夹webpack-exam,将dist中的html文件删除,接下来我们通过安装webpack的html插件来自动创建html文件。打开终端,输入npm i -D html-webpack-plugin
,就会开始安装html的插件,安装完成后,在package.json中的dependencies中会多出关键html插件的信息("html-webpack-plugin": "^2.30.1"
)。在webpack.config.js中,导入html-webpack-plugin,然后新增plugins,new出那个对象:
npm run dev
,重新打包,可以看到除了在dist文件夹中新生成app.js之外,还有一个index.html文件,其中还自动引入了脚本app.js(在终端中可以看到相关的文件信息)。
如果我们在src中有html文件并写好了一些结构,同样可以打包创建html文件。删除dist中的文件,在src中新建index.html,写一个div: 然后在webpack配置文件中进行配置: 在终端中再次进行打包
npm run dev
,在dist目录中出现app.js和hello.html。
loader
loader就是webpack用来预处理模块的,在一个模块被引入之前,会预先使用loader处理模块的内容。浏览器不能直接执行react的语法,只能执行直接的js,所以项目需要有react、babel等配置。
首先在项目中引入react相关,在终端输入命令npm i -S react react-dom
来安装react的依赖,在package.json的dependencies中就会出现"react": "^16.2.0"和"react-dom": "^16.2.0"
,表示已经成功引入react。此外,还要引入babel,在终端中输入npm i -D babel-loader babel-core
来安装babel的依赖,在package.json的devDependencies中出现"babel-core": "^6.26.0"和"babel-loader": "^7.1.2"
。到webpack配置文件中写入react的相关配置:
npm i -D babel-preset-react
,相关依赖
"babel-preset-react": "^6.24.1"
在配置中显示更新。在src的index.js中写代码:
重新打包运行
npm run dev
,在本地打开打开dist文件夹下的hello.html文件,即可看到:
服务器默认找 index.html, 如果你的文件名是 hello.html, 那就需要在地址栏手动输入 hello.html
devserver
这是一个服务器,让项目运行在服务器而不是本地。
在终端输入npm i -D webpack-dev-server
安装devserver服务器,在package.json的devDependencies中可以看到"webpack-dev-server": "^2.11.1"
。然后在scripts中添加命令start——"start": "webpack-dev-server"
在终端中输入命令npm run start
,devserver服务器就可以运行起来了。其中关于服务器的一些信息在终端会打印出来,服务器启动完成之后还会帮我们进行打包,打包后的东西并不是到本地(所以dist文件夹是空的),而是到内存中,供浏览器加载。 关于devserver还可以进行一些自定义的配置(webpack.config.json):
- 补充1:
start
是一个特殊词,所以npm run start
可以简写成npm start
- 补充2:
dev
和start
的对应: - 补充3:启动devserver后,终端显示编译完成,可以使用
control+c
退出来。 - 补充4:对于在webpack.config.js中,写上的依赖,在终端输入命令
npm i
即可安装。
引入css
webpack默认只会打包js代码,所以在打包其他内容的时候,就要使用相应的loader。
对于webpack来说,css、图片、字体等都是模块,加载不同的模块需要不同的loader。
比如在src中新建main.css,写上样式代码后,在index.js中(与main.css处于同目录下)引入main.css:
npm i -D style-loader
来安装style-loader,输入
npm i -D css-loader
来安装css-loader。启动devserver,即可看到css生效。
引入图片
在src新建组织文件和结构目录如下:
在style的main.css中写:body { background: url(../img/scm.jpg); }
在index.js中引入common中的样式:
import ‘./common/style/main.css';
对于webpack来说,css、图片、字体等都是模块,加载不同的模块需要不同的loader。所以这里我们需要使用处理图片的loader。在webpack.config.js中添加: 或 所以我们需要在终端中安装file-loader的依赖
npm i -D file-loader
。重启devserver即可。
在浏览器的控制台中可以看到,图片路径被打包后的显示方式和原来的是不一样的: 退出devserver,直接用
npm run dev
的方式打包后,在dist目录下可以看到图片被打包后的命名方式也和原先的是不一样的,和上面b529e...jpg一样。 如果我们在jsx中要使用img标签来引用这个图片,做法:
- 增强的file-loader:url-loader
url-loader不是帮我们输出图片加载路径,而是把图片编码成了另外一种形式,直接写进页面里。可是当图片很大时,这个字符串就会变得非常庞大,它会让加载文件也变得很大,所以当图片文件过大时,我们要让它打包,让它去请求,如果图片很小,直接使用url-loader写进页面。 在终端输入npm i -D url-loader
安装url-loader。如果要将所有图片用url-loader来处理,可以在webpack.config.js中这么写: url-loader是采用编码64的方式将图片写进页面里。当图片过大时,会让加载文件也变得庞大,所以我们可以进行一些限制,比如设置如果图片文件大约没有超过10kb就用url-loader的方式处理: 由于之前引入的图片都较大,所以我们可以看到在浏览器控制台中,img都是以路径的方式显示的。
引入字体
在common文件夹中新建文件夹fonts,里面放入一些字体文件:
在common/style/main.css中: 在index.js中: 在webpack.config.js中写入相关配置: 重启devserver即可: 只是使用打包功能可以在dist目录看到,文件中有多少个url,就会打包多少字体。有时候我们使用第三方的字体,有些字体是提供npm下载的。以fontawesome为例,在终端中输入npm i -S font-awesome
安装fontawesome字体。安装成功后,在package.json可以看到font-awesome的相关记录。在node_module文件夹中可以看到font-aewsome的相关依赖。在index.js中使用这个库的文字:
css模块化
在common/style/main.css中写入:
在index.html中: 其中,我们打印出的那个style,在浏览器控制台可以看到 在webpack.config.js中重新调整一下关于css的规则: 重启devserver,即可看到生效。在实际开发中,有些文件(比如common中的)我们并不希望被模块化,那些是需要在全局中起作用的,这时候可以修改webpack.congif.js中的css配置:
rules也是从后面向前进行匹配的。 在控制台中可以看到经过打包后的类名和写的原生的不同: 这些类名是被打包成base64格式的hash码。为了显示直观,我们在css模块化配置中加上属性localIdentName: 相应的,可以看到,path是所在文件夹(src-common),name为所在css文件名称(main),local为类名(ac),hash:base64:6为取前6位的hash码(BNVWVL)。使用less和scss
sass-loader依赖node-sass,所以安装sass-loader同时还要安装node-sass,在终端输出npm i -D sass-loader node-sass
来安装sass-loader和node-sass。
在src/common/style新建文件main.scss,内容为:.ot { font-size: 100px; }
在index.js中引入scss文件和使用类:
对于scss的模块化的做法:
除了node_modules、src/common中的scss文件,其他scss文件实行模块化: less-loader依赖less,所以安装less-loader同时还要安装less。在终端输入npm i -D less-loader less
啦安装相关依赖。
babel
babel,功能强大的js编译器,比如可以把es6代码编译成es5的代码,然后交给浏览器去执行。
babel是基于插件来运作。网址:babeljs.com
新建文件夹babel-exam。在终端中进入文件夹babel-exam,输入命令npm init
初始化一个package.json文件。安装babel-cli,在babel-cli的界面,根据提示在终端安装babel-cli(npm install --save-dev babel-cli,简写为npm i -D babel-cli),安装后即可在package.json看到babel-cli的配置显示。在文件夹babel-exam中新建文件夹src,在src中新建app.js,内容为:()=>{console.log(123);}class A {}。我们在终端来使用babel编译这个js文件中的es6代码,输入命令babel src/app.js
无效,因为babel是基于插件来运作的,没有安装相关插件,所以不能编译。在node_modules/.bin/中可以看到babel的相关依赖,所以在终端中输入命令”./node_modules/.bin/babel src/app.js”来进行编译,
"babel": "babel src/app.js"
,在终端输入
npm run babel
,被编译结果还是和上面的图保持一致。我们在babel官网/Docs/plugins中找到ES2015(ES6),首先我们找到箭头函数的插件(es2015-arrow-functions),点击进入后,根据提示在终端输入命令
npm i -D babel-plugin-transform-es2015-arrow-functions
安装编译箭头函数的babel插件,安装完毕后再package.json的依赖中可以看到插件信息的更新。在package.json中,修改scripts中的babel,改为
babel src/app.js —plugins transform-es2015-arrow-functions
,然后在终端输入
npm run babel
,可以看到箭头函数被编译为es5。同理我们也需要编译class A,在官网找到es6 class的插件页,根据提示在终端输入
npm i -D babel-plugin-transform-es2015-classes
安装插件,然后在package.json中的scripts的babel中新增es6类插件:
"babel": "babel src/app.js --plugins transform-es2015-arrow-functions,transform-es2015-classes"
,在终端中输入
npm run babel
,可以看到箭头函数和类都被正确编译为es5。 那么,如果有很多的babel插件,是不是都要去scripts中一个个增加呢?babel提供了.babelrc来解决这个问题。在官网中,找到Docs/.babelrc,可以看到怎么写.babelrc。在文件夹babel-exam中新建一个文件命名为.babelrc,将上面编译箭头函数和类的配置写到.babelrc文件中:
注意:
.babelrc plugin
中的插件名称要用双引号而不是单引号,因为在.babelrc
中是json
格式,全部用双引号。
然后在package.json中,scripts中的babel删除插件的那些字符:"babel": "babel src/app.js"
。在终端中输入npm run babel
,可以发现箭头函数和类也能被正确编译为es5。 将编译后的代码输出到文件:在package.json的scripts中,添加babel的指令:"babel": "babel src/app.js -o out/a.js"
,表示将编译后的代码输出到out文件夹的a.js文件中,在babel-exam文件夹中新建文件out,在终端输入命令npm run babel
,在out文件夹可以看到输出的a.js文件,里面就是babel编译后的js代码。
在官网的try it out中可以自己去试着看看编译后的es5代码。
babel-loader
babel预设
还是使用前面的webpack-exam为例。打开官网/plugins,可以看到几种官方预设,比如安装env预设,点击进入相应页面,根据提示在终端输入npm i -D babel-preset-env
安装env预设,所以在webpack.config.js中,babel-loader的预设除了react还有env:
npm i -D babel-plugin-transform-object-rest-spread
安装插件。接下来: 1、在.babelrc中加入这个插件:
{ "plugins": [“transform-object-rest-spread"] }
2、或者,在webpack.config.js的babel-loader中加入plugins:
以上两种做法二选一即可,没有在option中设定时,就会去.babelrc中查找 关于这个options中的参数,在官网/babel core/Options的表格中有API。
每次打包都会发现很慢,因为webpack.config.js中匹配的是所有的js文件(/.js$/),所以可以将比如node_modules中的js文件使用exclude排除开外:
.babelrc
怎么写预设和插件:
所以比如我们不在webpack.config.js中写babel的预设和插件,而是放到.babelrc中去写,也是可以的:
补充:比如每次打包东西到dist目录,在下次再打包前,有一个插件可以自动先删除dist文件中留下的上次打包的文件:在终端输入
npm i -D clean-webpack-plugin
安装插件,在webpack.config.js中引入:
这样每次打包前都会先删除dist文件夹的东西再生成打包出来的文件。
打包路径处理
精细的控制,打包分类
如果没有根据不同的模块(css、图片等资源都是模块)指定路径,会发现所有的资源会被打包到文件夹中,显得杂乱无章:
此publicPath和彼publicPath
publicPath在output和devserver中都有。
比如我们将打包的index.html放在输出目录的上一层:(注意htmlwebpackplugin中的filename,是将index.html向上一级进行打包)
可是,打包后dist中的index.html能够正常访问js和其他资源,用devserver进行访问时,就会出现问题: devserver访问文件是从硬盘和内存两个位置访问。webpack.config.js中的devServer有一个配置项为contentBase,如果在内存中访问不到,就会访问到contentBase指定的地方,比如把contentBase设置为common文件夹中,那么devserver服务器访问的是common文件夹(默认是访问如上图的根文件夹): 在devserver中也有一个属性publicPath,这个publicPath是服务器打包资源后的输出路径, 所以一般正确的打包路径方式为: 其中,如果是把index.html打包到更深层次: 服务器上访问时就要加上这一层:localhost:9000/haha webpack.config.js中的resolve: 以上表示引用资源(比如img标签src)时,先在”node_modules”文件夹中找,找不到再在根目录/src/common中找,然后在根目录/src/components中找,顺着顺序找,这个例子中在根目录/src/common/img中有jzz.jpg,所以可以正常显示图片。
关于npm
- 新建文件夹命名为npm-exam,在终端输入: cd npm-exam所在路径 atom ./ ——用atom打开文件夹 npm init ——初始化(对于接下来的选项自己看情况写) 写好后,在文件夹中会根据终端输入的内容创建出package.json:
- 安装依赖: npm install Lodash package.json中不会记录 npm install —save Lodash 覆盖安装,且package.json会记录 npm install —save-dev gulp
- 删除依赖:npm uninstall —save-dev gulp(package.json会删除相应记录)
原文发布时间为:2018年06月30日
作者:兔杰赛高
本文来源: 掘金 如需转载请联系原作者