webpack和npm-阿里云开发者社区

开发者社区> 我是小助手> 正文

webpack和npm

简介: 新建文件夹webpack-exam,组织和建立文件如下:
+关注继续查看

打包初体验

新建文件夹webpack-exam,组织和建立文件如下:

1 其中a.jsb.jsc.js内容分别如下: 1111 在文件夹下新建文件webpack.config.js,在文件中写配置: 1 目前浏览器并不能自动执行模块化代码,所以需要进行webpack的配置:打开终端,切换到文件夹所在目录内层,然后执行命令npm init -y,在文件夹中就会默认生成一个package.json,里面的配置参数均为默认,自己可以根据情况进行修改: 1 然后执行命令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.jsonscripts中将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的相关配置:

1 所以还要安装react的预设,在终端输入npm i -D babel-preset-react,相关依赖"babel-preset-react": "^6.24.1"在配置中显示更新。在src的index.js中写代码: 1重新打包运行npm run dev,在本地打开打开dist文件夹下的hello.html文件,即可看到: 1 服务器默认找 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):

留存问题:在webpack.config.js中,HtmlWebpackPlugin的filename要写成index.html,访问服务器才会显示相应页面

  • 补充1:start是一个特殊词,所以npm run start可以简写成npm start
  • 补充2:devstart的对应:
  • 补充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:

还要在webpack.config.js中写上css的相关loader: use里传一个数组,当遇到css文件时,先用css-loader来处理,当内容处理完成得到结果后,再由style.loader进行处理,也由此可见,use里是从后往前加载。然后在终端输入命令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文件和使用类:

然后在webpack.config.js中加上:(经过sass-loader处理的文件就是标准的css代码) 重启devserver,ok。

对于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”来进行编译,

1 还是没有被编译为es5,但至少这个命令是生效的。所以在package.json的scripts中我们可以加上一条:"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文件中: 1

注意:.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:

比如使用可以rest和spread对象的插件进行解析(这个还在experiment中,还未正式发布确定纳入):在官网中进入相应页面,根据提示在终端输入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、图片等资源都是模块)指定路径,会发现所有的资源会被打包到文件夹中,显得杂乱无章:

所以在webpack文件中进行一些配置: 打包后的所有文件在dist/assets中,其中字体文件位于dist/assets/fonts文件夹中,字体文件的命名格式就是上面配置中指定的。运行devserver,服务器也可以正常访问。

此publicPath和彼publicPath

publicPath在output和devserver中都有。
比如我们将打包的index.html放在输出目录的上一层:(注意htmlwebpackplugin中的filename,是将index.html向上一级进行打包)

对于其他的资源,在name属性中写上分类的文件夹: 进行打包后,index.html和assets文件夹同级且位于dist文件夹下,fonts、img等文件夹均在dist/assets中。然而打开index.html中看到,引用的js路径是js/app.js,这是因为在output中设置了publicPath,如果没有设置这个publicPath,那么index.html引用的js路径就是output中的assets再去拼接js(即assets/js/app.js),这里设置了publicPath,那么引用的js路径就是publicPath的值去拼接js/app.js,这里设置为空,所以拼接后的结果是js/app.js。publicPath是资源的基础路径,而且一定要以”/“结尾。所以将publicPath设置为”assets/”后,js就能正确引用(assets/js/app.js),图片、文字等资源在路径前也会加上“assets/”前缀。这个publicPath设置的值是在js、图片等资源前加前缀。
可是,打包后dist中的index.html能够正常访问js和其他资源,用devserver进行访问时,就会出现问题: devserver访问文件是从硬盘和内存两个位置访问。webpack.config.js中的devServer有一个配置项为contentBase,如果在内存中访问不到,就会访问到contentBase指定的地方,比如把contentBase设置为common文件夹中,那么devserver服务器访问的是common文件夹(默认是访问如上图的根文件夹): 在devserver中也有一个属性publicPath,这个publicPath是服务器打包资源后的输出路径, 所以一般正确的打包路径方式为: 11 其中,如果是把index.html打包到更深层次: 1 服务器上访问时就要加上这一层:localhost:9000/haha webpack.config.js中的resolve: 11 以上表示引用资源(比如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: 1
  • 安装依赖: npm install Lodash package.json中不会记录 npm install —save Lodash 覆盖安装,且package.json会记录 npm install —save-dev gulp 1
  • 删除依赖:npm uninstall —save-dev gulp(package.json会删除相应记录)



原文发布时间为:2018年06月30日

作者:兔杰赛高

本文来源:掘金 如需转载请联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
01_spring_ 简介| 学习笔记
快速学习01_spring_ 简介
9 0
Django框架介绍与安装
软件框架就是为实现或完成某种软件开发时,提供了一些基础的软件产品, 框架的功能类似于基础设施,提供并实现最为基础的软件架构和体系 通常情况下我们依据框架来实现更为复杂的业务程序开发 二个字,框架就是程序的骨架
4 0
SpringBoot 集成ElasticSearch的几种方式
SpringBoot 集成ElasticSearch的几种方式
9 0
学习vue3之路day1
学习vue3之路day1
18 0
学习vue3之路day2
学习vue3之路day2
5 0
mysql 数据库 日期函数
mysql 数据库 日期函数
14 0
Nginx-基本概念和使用
Nginx-基本概念和使用
10 0
节点表结构 | 学习笔记
快速学习节点表结构。
6 0
学习vue3之路day3
学习vue3之路day3
5 0
+关注
我是小助手
云栖直播
384
文章
6
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载