loder和插件是什么,如今暂且不表,看到后面你就懂了css
在前面的 vue(7)—— 组件化开发 — webpack(1) 讲解中,相信已经对webpack有必定了解了,想必不少朋友已经跃跃欲试了,准备要搞一个本身的小网站出来了,写上css,调整好代码,准备说干就干:html
一样的,由于之后的开发中,确定会有不少个css文件,可能一个vue组件就须要一个css文件,而后你又跟前面的js文件引入同样,在html文件里用link标签引入一堆的css吗?vue
这仍是那个用户体验的问题。node
因此,这里的解决方法仍是同js文件同样,用导包的方式: import ‘./XX.css’webpack
注意:导入css一般状况下是在入口组件里导入,而不是随便哪里均可以导入,固然最准确的仍是根据本身的代码逻辑作相应调整es6
index.html:web
已把link标签删除掉,经过导入编译好的bundle.js来插入cssnpm
好,在终端,使用命令npm run dev编译一下,发现报错了json
提示的意思是说你须要一个loader组件来控制这个css格式类型的文件bootstrap
这里要补充下,webpack.config.js是js文件,咱们定义的vue局部组件后缀也是js,而webpack默认只识别js文件,不能识别处理非js的文件,因此须要一个loder引导识别。因此在前面没遇到这个问题,如今遇到了
因此这里须要安装一个css的loader,是的,以上都是引子,就是为了引出这个loader
安装的时候记得安装两个,一个是css-loder这个是识别css后缀的文件,还要安装一个style-loader,这个是识别<style>标签的
npm i css-loader style-loader -D:
安装完成后,package.json的开发环境里已经自动写入:
在webpack配置文件里加入以下,webpack.dev.config.js
注意
关于这个很好理解,确定是先有css文件,再有的css样式对吧,主要就是这里的【!】是先取后面个的意思
module.exports = { entry: { //入口
name: './dist/app.js' //键名随意,值为项目入口js
}, output: { //出口
filename: './bundle.js' //键名必须为filename,值为项目编译好的js
}, watch: true, module:{ loaders:[ { test:/\.css$/, loader:'style-loader!css-loader' } ] } }
另外的webpack.prod.config.js配置是暂且无论,固然你也能够设置成同样的,记得把watch属性删掉
如今再使用命令 npm run dev 编译看看
编译成功,再次打开index.html文件:
link标签和style标签都是bundle自动加上去的
完美吧,终于能够显示css了
若是你在编译的时候遇到问题,好比遇到如下问题,请检查你的webpack.dev.config.js文件与css相关的配置是否有问题
注意:若是你遇到这样的写法,不是loders而是rules,不是loder而是use,这种也可行,这是新版的写法,不重要,效果是同样的
若是你的代码里有使用高级的css语言,好比less之类的,你一样须要从新安装一次loder,less对应的是less-loder,sass对应的是sass-loder,其余的就很少说了,能够去npm官网查
在写css时,确定会有引入一张图片的样式,好比这里:
给入口的div绑定了一个id为main属性:
我事先在项目的根目录放了一张图片,1.jpg,写上css样式,好比:
当完成以上操做的时候,这边的实时监听的已经报错了:
是的,又须要安装一个针对url的loader, npm i file-loader url-loader -D,网很差的话你可使用前面说过的nrm来安装
安装完,package.json文件里又自动多了两个参数:
再在webpack.dev.config.js里配置以下,图片格式有png,jpg,gif,jpeg,bmp,png,因此写了以下
注意:只添加url-loder,不用给file-loder
将那个错误的卡住的编译程序按ctrl+c终止掉,从新运行,没有报错:
打开网页:
右边的css样式就是url-loder把图片自动作base64编码了,而后经过浏览器读取base64编码,借此显示图片
直接复制按个base64编码地址,另起一个浏览器窗口,是能够直接打开的:
完美
由于图片用的base64编码,那么就能够稍微作限制,webpack.dev.config.js:
module.exports = { entry: { //入口
name: './dist/app.js' //键名随意,值为项目入口js
}, output: { //出口
filename: './bundle.js' //键名必须为filename,值为项目编译好的js
}, watch: true, module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test:/\.(jpg|jpeg|png|gif|bmp)$/, loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]' } ] } }
打开网页:
我添加的那几个参数的意思:
若是不给name属性,webpack会按本身的规则设定,把文件名取hash值,默认取32位,做为最后的名字
做为入口的app.js,这里说明一下,若是是引入下载的插件,不用写文件的路径,只有引入本身写的文件才须要写文件路径
webpack配置文件不用变,同上
module.exports = { entry: { //入口
name: './dist/app.js' //键名随意,值为项目入口js
}, output: { //出口
filename: './bundle.js' //键名必须为filename,值为项目编译好的js
}, watch: true, module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test:/\.(jpg|jpeg|png|gif|bmp)$/, loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]' } ] } }
在app.js入口组件里写入bootstrap的样式,给了几个比较简单的class名:
最后index.html显示结果:
固然你会发现,在项目根目录有编译过的图片文件:
字体就不用多说了,其实字体也是个url,因此用url-loader就好了,webpack配置:
而后你就能够在css样式里写入你须要的字体样式就好了,这里就不展现示例了,本身体会了
在前面已经了解了,浏览器默认不识别es6的语法,es即ECMAscript6,好比class定义类,浏览器就不识别,不知道后续的浏览器会不会识别这些了。
我在code1.js上定义了一个es6的类:
这边已经报错了:
此时怎么办呢?对了,仍是用loder
安装两个插件:npm i babel-preset-env babel-preset-stage-0 -D
注:若是babel-preset-stage-0用不了,能够卸载了安装babel-preset-stage-es2015,babelrc部分相应的也要改动对应的stage
安装另一套插件:npm i babel-core babel-loader bable-plugin-transform-runtime -D
注:
1.若是你的webpack版本比较低,安装的babel-loader没法使用(由于默认安装的最新版)
你能够安装指定版本,npm i babel-loader@7,我安装的7可用
2.若是你在安装 npm i babel-core babel-loader bable-plugin-transform-runtime -D 时出错:
多试几回,或者切换下npm安装源试试
好的,安装完成以后。直接在项目的根目录,建立一个【.babelrc】文件,写入以下参数:
{ "presets":["env","stage-es2015"], "plugins": ["transform-runtime"] }
注意对应你安装的stage版本,我安装stage-0用不了,已经切换了stage-es2015
以下修改:
module.exports = { entry: { //入口
name: './dist/app.js' //键名随意,值为项目入口js
}, output: { //出口
filename: './bundle.js' //键名必须为filename,值为项目编译好的js
}, watch: true, module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test:/\.(jpg|jpeg|png|gif|bmp)$/, loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]' }, { test:/\.(ttf|eot|svg|woff|woff2)$/, loader:'url-loader' }, { test:/\.js$/, loader:'babel-loader', exclude:/node_modules/ } ] } }
其实用path组件也能够,这个path组件是内置的,以下写也能够:
var path = require('path') module.exports = { entry: { //入口
name: './dist/app.js' //键名随意,值为项目入口js
}, output: { //出口
filename: './bundle.js' //键名必须为filename,值为项目编译好的js
}, watch: true, module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test:/\.(jpg|jpeg|png|gif|bmp)$/, loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]' }, { test:/\.(ttf|eot|svg|woff|woff2)$/, loader:'url-loader' }, { test:/\.js$/, loader:'babel-loader', exclude:path.resolve('./node_modules') } ] } }
exclude的意思是排除根目录下node_modules里的js文件,由于不排除的话,babel就会去编译node_modules里的js,消耗资源不说,编译了用不了
如今运行npm run dev再看:
若是编译时报错:
意思就是说最后那个‘./node_module’没法识别。
因此在exclude部分,你要嘛用path.resolve('./node_modules'),要嘛用/node_modules/,其余的写法都是错的
正确编译:
其实已经识别了,可是说我这有语法错误
好的,我稍微修改一下,立马不报错了
好的,这里这个babel算是比较高级的用法了,之后还会用到,就很少解释了。目前你就记住,babel是把es6的高级语法编译成浏览器可识别的低级语法就好了
在之后的开发中,可能有这种需求:
当咱们已经肯定把项目码好,准备把代码输出来,而后直接把输出来的相关文文档拷走便可,这样的需求,怎么办?
彻底可让webpack编译的时候自动生成html文件,而不是咱们本身去手动的设置,由于咱们改动的目前只是开发环境,有些东西其实对于生产环境来讲是不须要的,因此这个怎么操做呢?
而后在webpack.prod.config.js文件里做以下配置:注意此次是生产环境的那个webpack配置文件了:
var path = require('path') var htmlwebpackplugin = require('html-webpack-plugin') module.exports = { entry: { //入口
name: './dist/app.js' //键名随意,值为项目入口js
}, output: { //出口
path:path.resolve('./src'),//相对转绝对,设定一个输出文件路径
filename: './bundle.js' //键名必须为filename,值为项目编译好的js
}, plugins:[ new htmlwebpackplugin({ template:`./index.html` // html文件参照物,即开发环境下的html文件 }) ], module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test:/\.(jpg|jpeg|png|gif|bmp)$/, loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]' }, { test:/\.(ttf|eot|svg|woff|woff2)$/, loader:'url-loader' }, { test:/\.js$/, loader:'babel-loader', exclude:/node_modules/ } ] } }
其余不用变,把刚才的测试环境卡住的npm run dev停掉,用npm run build:
以后则会在根目录下自动生成一个src文件夹:
打开index.html,发现一个小问题,出现了两个bundle。
由于使用npm run build时,会自动给咱们配置一个bundle,可是咱们的参照的那个index.html文件里原本就有了一个bundle,因此,把参照物里的bundle删除:
再次使用npm run build编译:
这下正常了,完美
因此,这个 var htmlwebpackplugin = require('html-webpack-plugin')有两个做用:
1.参照开发环境的文件打包
2.自动编译好并把打包好的bundlue.js文件添加进html文件里
最后还有个插件,一个伪服务器插件 http-server。若是你使用的是pycharm开发的话,pycharm自带了这个功能,在html文件直接点右上角的浏览器图标便可自动挂载在本地端口。详细的就很少说了
由于一下子要直接调用命令使用,因此安装在了全局
使用命令 hs -o -p 8888,意思是经过8888端口启动
若是你设置默认的浏览器的话,会自动启动默认浏览器,而后自动开始一个新窗口直接打开:
换了一个浏览器,正常访问:
又来个问题了,若是你每改一次都要刷新一次吗?很烦对不对,因此有必要有一个工具当咱们改完代码,不用刷新浏览器页面,自动的更新,相似刚才咱们用的webpack配置文件,实时监听的效果:
注意,安装webpack-dev-server时,因为新版须要webpack-cli(cli即脚手架,后面会讲到)的支持,因此最好安装低版本的:
webpack.dev.config.js:
其实跟上面的同样没有变,注意是开发环境下的配置文件,不是生产环境下的配置文件
module.exports = { entry: { //入口
name: './dist/app.js' //键名随意,值为项目入口js
}, output: { //出口
filename: './bundle.js' //键名必须为filename,值为项目编译好的js
}, watch: true, module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test:/\.(jpg|jpeg|png|gif|bmp)$/, loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]' }, { test:/\.(ttf|eot|svg|woff|woff2)$/, loader:'url-loader' }, { test:/\.js$/, loader:'babel-loader', exclude:/node_modules/ } ] } }
package.json配置文件做以下修改:
"scripts": { "dev": "webpack-dev-server --open --hot --inline --config ./webpack.dev.config.js", "build": "webpack --config ./webpack.prod.config.js" },
其实这一步不用作也能够,由于不影响,可是为了和后面要说的原理对应,因此改了文件名
把以前bundle文件改成:bundle.backup.js:
如今再用命令 npm run dev启动编译
自动打开浏览器:
我如今修改一下文字的颜色,由于背景图颜色和字体颜色有点不搭配我改为黑色:
这边的watch 发生变化,自动在从新编译:
再次打开浏览器,根本不用刷新,已经自动运用上css了,完美,这才是咱们但愿的开发环境
而此时,项目目录下根本没有bundle.js文件:
刚才咱们用的bundle.js文件已经更名了,因此不多是以前咱们生成的bundle文件产生的效果
这就是webpack-dev-server的特性:
自动监听编译,而且生成了一个虚拟的bundle.js文件在内存上,而且在项目的根目录中虚拟存在
设定热更新还有另外一种写法:
代码:
var path = require('path') var htmlwebpackplugin = require('html-webpack-plugin') module.exports = { entry: { //入口 name: './dist/app.js' //键名随意,值为项目入口js }, output: { //出口 path:path.resolve('./src'),//相对转绝对,设定一个输出文件路径 filename: './bundle.js' //键名必须为filename,值为项目编译好的js }, plugins:[ new htmlwebpackplugin({ template:`./index.html` // html文件参照物,即开发环境下的html文件 }) ], module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test:/\.(jpg|jpeg|png|gif|bmp)$/, loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]' }, { test:/\.(ttf|eot|svg|woff|woff2)$/, loader:'url-loader' }, { test:/\.js$/, loader:'babel-loader', exclude:/node_modules/ } ] } }
package.json文件直接一个webpack 不用给任何参数:
"scripts": { "dev": "webpack-dev-server --config ./webpack.dev.config.js", "build": "webpack --config ./webpack.prod.config.js" },
npm run dev:
自动打开浏览器:
可是这种方式相对前面那个更有难度一点,效果同样的
以上全部相关代码打包整合:点我 (由于博客园文件限制最大为10M,我所有代码打包已经超过了,因此node_modules文件自行初始化自行安装第三方插件)
本节说了不少插件,有点繁琐,可是基本都是后面会用到的,多看多熟悉