30分钟手把手教你学webpack实战css
阅读目录html
什么是webpack? 他有什么优势?前端
首先对于不少刚接触webpack人来讲,确定会问webpack是什么?它有什么优势?咱们为何要使用它?带着这些问题,咱们来总结下以下:node
Webpack是前端一个工具,可让各个模块进行加载,预处理,再进行打包,它能有Grunt或Gulp全部基本功能。优势以下:react
二:如何安装和配置webpack
首先个人项目目录结构是:文件名叫webpack,里面只有一个main.html,代码以下:git
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="src/react.min.js"></script> </head> <body> <div id="content"></div> <script src="build/build.js"></script> </body> </html>
还有一个文件夹src,该文件夹存放了二个js文件;react.min.js源文件和main.js文件,main.js源码以下:es6
/* 内容区模块代码 */ var ContentMode = React.createClass({ render: function(){ return ( <div className="ContentMode"> <div class="contents">{this.props.contents}</div> {this.props.children} </div> ) } }); /* 页面div封装 上面三个模块 */ var Page = React.createClass({ render: function(){ return ( <div className="homepage"> <ContentMode contents ="longen">this is one comment</ContentMode > <ContentMode contents ="longen2">this is two comment</ContentMode > </div> ) } }); /* 初始化到content容器内 */ React.render( React.createElement(Page,null),document.getElementById("content") );
该代码是React.js代码,是react.js入门学习一中的代码复制过来的 为了演示;github
安装步骤以下:web
首先咱们须要在根目录下生成package.json文件,须要进入项目文件内根目录下执行以下命令:npm init
如上经过一问一答的方式后会在根目录下生成package.json文件,以下所示:
2 . 经过全局安装webpack
执行命令以下:npm install -g webpack 以下所示:
在c盘下会生成node_modules文件夹中会包含webpack,此时此刻咱们可使用webpack命令了;
3. 配置webpack
每一个目录下都必须有一个webpack.config.js,它的做用就比如Gulpfile.js、或者 Gruntfile.js,就是一个项目配置,告诉webpack须要作什么。
以下是个人webpack.config.js代码以下:
module.exports = { entry: "./src/main.js", output: { filename: "build/build.js" }, module: { loaders: [ //.css 文件使用 style-loader 和 css-loader 来处理 { test: /\.css$/, loader: "style!css" }, //.js 文件使用 jsx-loader 来编译处理 { test: /\.js$/, loader: "jsx-loader" } ] }, resolve: { extensions: ['', '.js', '.jsx'] }, plugins: [] };
entry 是页面中的入口文件,好比我这边的入口文件时main.js
output: 是指页面经过webpack打包后生成的目标文件放在什么地方去,我这边是在根目录下生成build文件夹,该文件夹内有一个build.js文件;
resolve: 定义了解析模块路径时的配置,经常使用的就是extensions; 能够用来指定模块的后缀,这样在引入模块时就不须要写后缀,会自动补全。
plugins: 定义了须要使用的插件,好比commonsPlugin在打包多个入口文件时会提取公用的部分,生成common.js;
module.loaders:是文件的加载器,好比咱们以前react须要在页面中引入jsx的js源码到页面上来,而后使用该语法,可是经过webpack打包后就不须要再引入JSXTransformer.js;看到上面的加载器;好比jsx-loader加载器就是表明JSXTransformer.js的,还有style-loader和css-loader加载器;所以在使用以前咱们须要经过命令把它引入到项目上来;所以须要以下命令生成下;
jsx-loader加载器 npm install jsx-loader --save-dev 以下:
Style-loader加载器 npm install style-loader --save-dev 以下:
css-loader 加载器 npm install css-loader --save-dev 以下:
局部安装webpack 执行命令:npm install webpack --save-dev
咱们这边干脆把gulp的全局安装和在项目中局部安装也安装下,稍后有用~
Gulp全局安装 npm install -g gulp 以下:
在项目文件内,gulp局部安装 使用命令 npm install gulp --save-dev 以下所示:
所以在咱们文件夹node_modules下生成文件以下:
如今咱们来执行命令 webpack; 以下所示:
便可在根目录下生成一个build文件夹中build.js 以下所示:
咱们还可使用以下命令:webpack --display-error-details 命令执行,这样的话方便出错的时候能够查看更详尽的信息;好比以下:
如今咱们再来刷新下页面;看到以下:
能够看到页面渲染出来了,咱们接着来看看页面中的请求:
能够看到只有一个文件react.min.js的源文件和build.js 咱们刚刚生成的build.js文件了,所以咱们经过webpack进行打包后,咱们如今就再也不须要和之前同样引入JSXTransformer.js了。咱们还能够看看build.js内生成了那些js,这里就不贴代码了,本身能够看看了~
上面是使用webpack打包;如今咱们再来看看使用第二种方案来打包~
使用gulp来进行打包
咱们知道使用gulp来打包的话,那么咱们须要在根目录下须要新建 Gulpfile.js;
所以咱们这边Gulpfile.js的源码以下:
var gulp = require('gulp'); var webpack = require("gulp-webpack"); var webpackConfig = require("./webpack.config.js"); gulp.task('webpack', function () { var myConfig = Object.create(webpackConfig); return gulp .src('./src/main.js') .pipe(webpack(myConfig)) .pipe(gulp.dest('./build')); }); // 注册缺省任务 gulp.task('default', ['webpack']);
而后webpack.config.js代码变为以下:
module.exports = { entry: "./src/main.js", output: { filename: "build.js" }, module: { loaders: [ //.css 文件使用 style-loader 和 css-loader 来处理 { test: /\.css$/, loader: "style!css" }, //.js 文件使用 jsx-loader 来编译处理 { test: /\.js$/, loader: "jsx-loader" } ] }, resolve: { extensions: ['', '.js', '.jsx'] }, plugins: [] };
便可,而后再在命令行中输入gulp便可生成build/build.js了;以下所示:
Github上的代码以下: https://github.com/tugenhua0707/webpack/ 本身能够把压缩包下载下来运行下便可。
三:理解webpack加载器
Webpack提供了一套加载器,好比css-loader,less-loader,style-loader,url-loader等,用于将不一样的文件加载到js文件中,好比url-loader用于在js中加载png/jpg格式的图片文件,css/style loader用于加载css文件,less-loader加载器是将less编译成css文件;
配置加载器
module.exports = { entry: "./src/main.js", output: { filename: "build.js", path: __dirname + '/assets/', publicPath: "/assets/" }, module: { loaders: [ {test: /.css$/, loader: 'style!css'}, {test: /.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] } resolve: { extensions: ['', '.js', '.jsx'], //模块别名定义,方便后续直接引用别名,无须多写长长的地址 alias: { a : 'js/assets/a.js', // 后面直接引用 require(“a”)便可引用到模块 b : 'js/assets/b.js', c : 'js/assets/c.js' } }, plugins: [commonsPlugin, new ExtractTextPlugin("[name].css")] }
module.loader: 其中test是正则表达式,对符合的文件名使用相应的加载器.
/.css$/会匹配 xx.css文件,可是并不适用于xx.sass或者xx.css.zip文件.
url-loader 它会将样式中引用到的图片转为模块来处理; 配置信息的参数“?limit=8192”表示将全部小于8kb的图片都转为base64形式。
entry 模块的入口文件。依赖项数组中全部的文件会按顺序打包,每一个文件进行依赖的递归查找,直到全部模块都被打成包;
output:模块的输出文件,其中有以下参数:
filename: 打包后的文件名
path: 打包文件存放的绝对路径。
publicPath: 网站运行时的访问路径。
relolve.extensions: 自动扩展文件的后缀名,好比咱们在require模块的时候,能够不用写后缀名的。
relolve.alias: 模块别名定义,方便后续直接引用别名,无须多写长长的地址
plugins 是插件项;
四:理解less-loader加载器的使用
咱们先来理解下less-loader加载器,其余的sass-loader也是一个意思,这边不会对全部的预处理的css作讲解,less-loader加载器是把css代码转化到style标签内,动态插入到head标签内;咱们先来看看我项目的结构以下:
咱们如今css文件下有一个main.less 代码以下:
@base: #f938ab; html,body { background:@base; }
Src文件下有一个main.js文件 此js文件时入口文件;里面的代码以下:
// css
require('../css/main.less');
webpack.config.js 代码配置以下:
module.exports = { entry: "./src/main.js", output: { filename: "build.js", path: __dirname }, module: { loaders: [ //.css 文件使用 style-loader 和 css-loader 来处理 { test: /\.less$/, loader: "style!css!less" } ] }, resolve: { extensions: ['', '.js', '.jsx'] }, plugins: [] };
Gulpfile.js代码以下(注意:这边既能够须要此文件使用gulp进行运行打包,也能够不须要此文件,直接使用webpack进行打包;二种方式任选其一)。
var gulp = require('gulp'); var webpack = require("gulp-webpack"); var webpackConfig = require("./webpack.config.js"); gulp.task('webpack', function () { var myConfig = Object.create(webpackConfig); return gulp .src('./src/main.js') .pipe(webpack(myConfig)) .pipe(gulp.dest('./build')); }); // 注册缺省任务 gulp.task('default', ['webpack']);
所以咱们须要安装 style-loader css-loader 和 less-loader 以下所示:
安装完成后,咱们查看咱们的项目的根目录node_modules下多了以下几个文件:
如上配置后,咱们进入项目后 运行下 gulp或者 webpack命令既可,在build文件夹内会生成build.js,此JS是动态生成style标签并解释正常的css插入到文档head标签内;咱们能够运行下页面,查看代码看下以下:
所以咱们能够看到页面生效了;为了更好的demo测试,我把代码放到以下github上,本身能够下载下来运行下既可:https://github.com/tugenhua0707/webpack-less-loader
五:理解babel-loader加载器的含义
babel-loader加载器能将ES6的代码转换成ES5代码,这使咱们如今可使用ES6了;咱们在使用以前,咱们须要安装babel-loader
执行命令:npm install babel-loader –save-dev 以下所示:
如上安装完后,咱们在根目录node_modules会生成文件,以下所示:
如今咱们能够在webpack.config.js里面moudle.loaders配置加载器了,以下代码:
{test: /\.js$/, loader: 'babel', exclude: '/node_modules/'}
所以webpack.config.js代码变成以下:
// 使用webpack打包 module.exports = { entry: "./src/main.js", output: { filename: "build.js", path: __dirname }, module: { loaders: [ {test: /\.js$/, loader: 'babel', exclude: '/node_modules/'} ] }, resolve: { extensions: ['', '.js', '.jsx'] }, plugins: [] };
下面咱们再来看看我项目中的目录结构以下:
咱们在看看src源文件有下面几个文件
React.min.js是react源码,这个很少说,bind.js的ES6的代码以下:
// es6的语法 let LOADER = true; module.exports = LOADER;
main.js 是页面的入口文件;代码以下:
let loader = require('./bind'); console.log(loader);
let是ES6的语法 至关于js中的var定义变量的含义; 接着打印下bind模块中 打印为true;
最后执行gulp以下:
在控制台中打印true;我把源码放在github上,有须要的同窗能够本身下载下来运行下便可;以下github(我2年没有使用github,如今从新使用,为了更好的演示demo问题); https://github.com/tugenhua0707/webpack-babel-loader
六:了解下webpack的几个命令
咱们下面来了解下 webpack -w
以下所示:
好比我在js文件里面随便增长一点代码后,保存后,再刷新页面便可能够看到代码生效了,无需从新运行webpack或者gulp,使用webpack -w 能够实时打包。 webpack -p 的含义是对进行打包后的文件进行压缩代码;好比我在以前使用chrome看打包后的代码以下:
如上能够看到,代码是未压缩的,可是当我在控制台命令行中运行 webpack -p 命令后,以下所示:
咱们如今再到控制台上看下代码变成已经压缩后的代码了,以下所示:
webpack -d 是提供未压缩以前的源码 方便代码中的调式;以下所示:
当我运行如上所示后,咱们再来看看刚才已经压缩后的代码变成什么样子呢?以下所示:
如上代码能够看到 咱们进行压缩后的代码,经过运行 webpack -d 命令后,便可还原未压缩的代码,这样的话就能够方便咱们线上调式代码了。
咱们再来看看目录下 会生成map文件,以下所示:
七:webpack对多个模块依赖进行打包
经过一刚开始咱们了解到 webpack支持commonJS和AMD两种模块机制进行打包,所以咱们如今来针对代码中使用commonJS和AMD机制进行作一个demo;
Src源文件增长module1.js module2.js module3.js 代码分别以下:
module1.js 代码: // module1.js require(["./module3"], function(){ console.log("Hello Webpack!"); }); Module2.js代码以下: // module2.js,使用的是CommonJs机制导出包 module.exports = function(a, b){ return a + b; } Module3.js代码使用AMD机制 // module3.js,使用AMD模块机制 define(['./module2.js'], function(sum){ return console.log("1 + 2 = " + sum(1, 2)); }); // 入口文件 main.js 代码以下: require("./module1");
咱们能够运行下 webpack后 在根目录下生成以下文件:
其中1.build文件夹是commonJS生成的 里面是commonJS的代码;咱们再查看页面的代码以下能够看到:
咱们继续查看控制台输出以下:
为止咱们能够看到webpack打包能够支持commonJS模块和AMD模块。
具体的代码 能够查看个人github上的源码:
https://github.com/tugenhua0707/webpack-multi-module-depend
八:如何独立打包成样式文件
有时候咱们不想把样式打在脚本中,而是想独立css出来,而后在页面上外链css,这时候咱们须要 extract-text-webpack-plugin 来帮忙:咱们首先须要安装 extract-text-webpack-plugin:以下: npm install extract-text-webpack-plugin –save-dev 以下所示:
而后在目录下会生成以下:
如今咱们须要看看webpack.config.js 配置变成以下:
var ExtractTextPlugin = require("extract-text-webpack-plugin"); // 使用webpack打包 module.exports = { entry: "./src/main.js", output: { filename: "build.js" }, module: { loaders: [ //.css 文件使用 style-loader 和 css-loader 来处理 { test: /\.less$/, loader: ExtractTextPlugin.extract( 'css?sourceMap!' + 'less?sourceMap' ) } ] }, resolve: { extensions: ['', '.js', '.jsx'] }, // 内联css提取到单独的styles的css plugins: [new ExtractTextPlugin('styles.css')] };
配置完成后 咱们gulp运行下便可,在build文件夹内会生成2个文件,一个是build.js 处理模块的文件 另外一个就是咱们的styles.css了;咱们查看下以下所示:
接着在html文件这样引入便可:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="src/react.min.js"></script> <link rel="stylesheet" href="build/styles.css"/> </head> <body> <div id="content"></div> </body> </html>
在页面上运行如下;便可看到效果:咱们能够看下请求数:
具体的代码demo能够看个人github 以下:
https://github.com/tugenhua0707/extract-text-webpack-plugin
注意:node_modules模块没有上传上去,git上传不上去,总是提示Filename too long的错误,因此就没有上传,须要本身在本地安装以下模块:
九:如何打包成多个资源文件
咱们在开发页面的时候,有时候须要有多个入口文件,作到文件是按需加载,这样就可使用缓存提高性能;那么咱们接下来须要如何配置呢?如今咱们继续作demo,如今好比我如今的项目文件结构以下:
咱们直接看 webpack.config.js配置代码变成以下:
module.exports = { entry: { "main": "./src/main.js", "index": "./src/index.js" }, output: { filename: "[name].bundle.js" } };
从上面的配置代码咱们能够看到 entry如今变成了一个对象了,而对象名也就是key会做为下面output的filename属性的[name]。固然entry也能够是一个数组。
所以咱们直接 gulp运行下便可 在build文件下 生成2个入口文件 如上面的截图所示:github源码地址以下:
https://github.com/tugenhua0707/webpack-many-page
如今咱们能够根据不一样的页面 引入不一样的入口文件,实现按需加载文件。
十:关于对图片的打包
咱们知道图片是使用url-loader来加载的,咱们既能够在css文件里url的属性;以下:
#content{ width:170px; height:60px; background:url('../images/1.jpg') no-repeat; }
咱们还能够直接对元素的src属性进行require赋值。以下代码:
var img = document.createElement("img"); img.src = require("../image/1.jpg"); document.body.appendChild(img);
我这边直接来说第一种在css文件里的url属性进行打包;
首先来看看我项目的目录结构以下:
Css文件 main.css代码以下:
#content{ width:170px; height:60px; background:url('../images/1.jpg') no-repeat; }
JS文件main.js代码以下:
require('../css/main.css');
Webpack.config.js配置文件代码以下:
// 使用webpack打包 module.exports = { entry: { "main": "./src/main.js" }, output: { path: './build/', filename: "build.js" }, module: { loaders: [ {test: /.css$/, loader: 'style!css'}, {test: /.(png|jpg)$/, loader: 'url?limit=8192'} ] } };
直接运行webpack 能够生成build目录,build目录下会生成2个文件 一个是图片打包后,另一个是build.js。接着咱们再在页面运行下页面,发现有一个问题,以下:
页面调用图片的url是根目录下的,不是我打包后的 build文件夹下,因此会致使图片路径找不到的问题;所以这边有一点点没有完成的任务,但愿有兴趣的童靴能够帮助完成~ 不过图片确实是已经打包好了,为了方便,咱们仍是提供github源码吧!以下所示: