webpack 3.0+基础学习
2017-11-23 16:52
489 查看
一个webpack demo
首先是建立项目结构根目录新建 src 文件夹 (开发环境时的代码)
根目录新建 dist 文件夹(生产环境的代码)
webpack 打包的本质是把 src下的入口文件 entry.js 文件,及其相关联的文件,打包成bundle.js文件,并且放在 dist 文件夹下面
webpack 的打包命令:
如果是全局安装的webpack :
$webpack src/entry.js dist/bundle.js。
如果是项目中安装的webpack :
$./node_modules/.bin/webpack src/entry.js dist/bundle.js
一般我们webpack不会使用全局安装的方式,会造成版本冲突导致的问题。而使用项目中安装的webpack 命令行每次打包输入又太长,可以将命令行写进
package.json文件里面的
script标签中:
"scripts": { "bundle":"./node_modules/.bin/webpack src/entry.js dist/bundle.js" },
这样每次打包只需要
$npm run bundle就可以了。
小技巧: bundle 改成 start ,只需要
npm start。
全局安装
live-server这个插件可以在本地跑一个服务器,使项目跑在
8080这个端口。
webpack配置文件
在项目的根目录新建webpack.config.js文件,配置的基本结构:
module.exports = { entry: {}, output: {}, module: {}, //模块解读css,打包css,图片转换压缩等配置。 plugins: [], //插件 devServer: {}, //配置开发服务 }
上面将入口出门配置信息写进了
script脚本里面,然后使用
npm start来跑这段脚本,也就是跑这段命令,这种方式来配置是非常单一的,没有更多的配置选项,如果做多入口多出口的配置就无法实现了。正确开发的姿势是将配置信息写进
webpack.config.js文件中:
const path = require('path'); //注意引入 path 模块 module.exports = { entry: { entry:'./src/entry.js' //入口文件路径 }, output: { path:path.resolve(__dirname,'dist'), //出口文件路径 filename:'bundle.js' //打包后的文件名 } }
path.resolve(__dirname,'dist')代码解读:
path:node核心模块之一,需要引入
path。
__dirname:当前文件所在目录的完整绝对路径。
resolve:
resolve会将参数中的路径或路径片段的序列解析为一个绝对路径,这样即使项目迁移,地址变更,只要保证相对路径正确即可。
代码解读:出口文件存放路径为当前文件夹下的
dist文件夹中。
多入口 多出口 配置
在src下新建一个
entry2.js文件,也就是第二个入口文件,加入js代码,更改配置。
entry: { //固定命名 entry: './src/entry.js', //这里的entry名字是自己定义的 entry2: './src/entry2.js', }, output: { path:path.resolve(__dirname,'dist'), filename:'[name].js' //[name] 打包的出口文件名 和 入口文件名是一样的 },
更改
dist/index.html中引入的js文件,就可以查看效果了。
注意:两个入口肯定需要两个出口文件对应
服务和热更新
自己配置一个本地的服务器,首先需要在项目中安装webpack-dev-server这个包。
npm i webpack-dev-server --save-dev
shell 中输入命令
webpack-dev-server,是无法识别的,因为没有全局安装,环境变量中也就没有存在命令所在的目录。我们需要再
package.json中加入:
"server":"./node_modules/.bin/webpack-dev-server --open"
后面加上参数
--open运行后直接弹出浏览器
这样配置后
npm run server他会去找
webpack.config.js文件中的服务器配置信息:
devServer: { contentBase: path.resolve(__dirname, 'dist'), //监听的文件夹 host: 'localhost', //服务器地址,本机ip地址,不建议使用locahost ,防止映射表被修改,出现解析不到的情况。ifconfig 查看 本机ip compress: true,//服务器端压缩 port:1717 //服务器端口,默认80 },
注意:在翻墙的情况下
host:填写本机ip 会报错,使用
localhost
打包css文件
首先需要安装两个包style-loader
css-loader来实现对css 文件的转换。
npm i style-loader css-loader --save-dev
style-loader:处理css中的 url
css-loader:处理css中的样式
在src文件夹中建立css文件,并且在 入口文件 或者 入口依赖的其他js文件 中引入:
import css from './css/index.css';
webpack.config.js中的配置:
module: { rules: [ { test: /\.css$/, //用正则表达式的形式来找到处理的文件 use: ['style-loader', 'css-loader']//使用哪些loader来处理 } ] },
另一种常用写法可以使每个
loader可以配置选项:
module: { rules: [ { test: /\.css$/, use: [{ loader:"style-loader" }, { loader:"css-loader" }] } ] },
压缩js文件
对js文件做代码压缩,需要使用到 webpack 内置的uglifyjs-webpack-plugin这个插件。
//webpack.config.js const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); plugins: [ new UglifyJSPlugin() ],
然后
npm start发现打包出来的代码被压缩了。
这里遇到了一个坑。。。
接上一步开启服务器
npm run server,命令行报错 ERROR in entry.js from UglifyJs
Unexpected token: name (urlParts) [entry.js:325,4]
原因在于:没有区分 开发环境 和 生产环境 。
开发环境中代码是不需要压缩的。如果压缩了,调试没有办法找到对应的行号。代码压缩只需要再 生产环境 中进行,在开发环境中压缩代码,跑服务器造成了冲突,具体情况不清楚。
正常的项目开发是不会产生这样的问题的,都会有一个 开发使用的配置文件 和 生产使用的配置文件 。
HTML文件的打包
一般项目开发是严格区分 开发环境 和 生产环境 的,也就是src文件是我们的 开发环境 的项目代码文件夹,
dist文件夹是打包后自己生成的,不需要我们自己去创建。把
index.html文件放在
src目录下面,删除文件里面的
script标签,
html-webpack-plugin会自动帮我们加入引入js的
script标签。
npm i -D html-webpack-plugin
项目中的配置
//webpack.config.js const htmlPlugin = require('html-webpack-plugin') plugins: [ new htmlPlugin({ minify: { removeAttributeQuotes: true,//去掉标签中的引号 }, hash: true, //引用js时有缓存,加上hash后每次都会给个不同的字符串。 template:'./src/index.html' }) ],
打包后发现自动的新建了
dist文件夹和里面的打包文件。
这里注意配置的写法,大括号太多。我写错了导致打包后的文件异常,找了半天问题 (⊙﹏⊙)b。
项目中引入图片
css中引入图片
eg:/* src/css/index.css */ #img{ background-image:url(../img/img.png); width:120px; height:101px; }
首先需要安装
url-loader这个插件
配置
webpack.config.js文件:
{ rules:[ { test: /\.(png|jpg|gif)$/, use: [{ loader: 'url-loader', options: { limit:5000, } }] } ] }
注意:loader是不需要引入的。
limit:5000的意思是:图片大于5000字节,自动拷贝图片到
dist文件,并且在
bundle.js文件中(打包后的js文件)修改正确的路径(包含了
file-loader的一些功能)。如果小于5000,会生成base64位格式的图片直接插入到js文件中,好处是减少了http请求。
HTML中引入图片
webpack 官方是不建议我们在html中引入图片的,如果有这种需求,直接添加image标签引入图片,打包后发现,图片并没有被打包到
dist文件夹下面,因为图片没有被依赖。
eg:
<-- index.html --> <div><image src="./img/img.png"/> </div>
解决这个问题需要装
html-withimg-loader插件,然后配置:
//webpack.config.js loaders: [ { test: /\.(htm|html)$/i, loader: 'html-withimg-loader' } ]
CSS样式分离和publickPath设置
CSS样式分离
一般项目中css文件都是直接打包进bundle.js文件中去的,这样可以减少
http请求。但是在某些时候,我们不想把 css 文件打包进入
bundle.js文件中,比如:一个项目全是靠css样式来布局,js代码非常少得情况下,项目总监要求把项目交给切图仔维护等需求。如何实现呢:
npm i -D extract-text-webpack-plugin
//webpack.config.js const extractTextPlugin = require('extract-text-webpack-plugin') plugins:[ new extractTextPlugin("css/index.css") //把css文件放在服务器的根目录(这里是dist文件夹下),下的css文件夹中。 ]
css loader 也需要做一些更改
{ test: /\.css$/, use: extractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) }
publickPath设置
打包代码,跑本地服务器,这时候发现图片没有了,查看打包后的项目结构,发现css文件中的路径有问题。这时候需要设置
publiPath公用路径,解决静态文件的路径问题。
//webpack.config.js var website = { publicPath:'http://192.168.1.105:1717/' //注意这里的斜杠,ip为服务器ip(在这里是你的计算机ip) } output: { ... publicPath:website.publicPath }
重新打包,css文件中图片的路径变为了正确的绝对路径。
打包和分离LESS
打包LESS文件到 bundle.js 文件中
首先需要安装less、
less-loader这两个包
npm i -D less less-loader
webpack.config.js 配置
// webpack.config.js module.exports = { ... module: { rules: [{ test: /\.less$/, use: [{ loader: "style-loader" // creates style nodes from JS strings }, { loader: "css-loader" // translates CSS into CommonJS }, { loader: "less-loader" // compiles Less to CSS }] }] } };
注意loaderde顺序,顺序错误会造成打包失败的情况。
然后编写LESS文件,引入到入口JS文件中,就可以了。
分离LESS文件
和分离css文件类似,需要用到extract-text-webpack-plugin这个包,上面已经安装了,这里不需要安装了。
//webpack.config.js const extractTextPlugin = require('extract-text-webpack-plugin') { test: /\.less$/, use: extractTextPlugin.extract({ use: [ { loader: 'css-loader' }, { loader: 'less-loader' } ], fallback:'style-loader' }) } plugins: [ new extractTextPlugin("css/index.css") ]
打包后会把LESS中的样式转换成CSS样式,并且打包进index.css 文件中去,这里并不会新建一个CSS文件。
SASS的打包和分离
SASS的打包
将SASS转换成CSS,并且打包进bundle.js文件中去:npm i -D node-sass sass-loader
//webpack.config.js { test: /\.scss$/, //注意这里的 SCSS,不是SASS use: [ { loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'sass-loader' } ] }
在项目中引入打包就可以了。
SASS的分离
和LESS分离步骤几乎一样//webpack.config.js const extractTextPlugin = require('extract-text-webpack-plugin') { test: /\.scss$/, use: extractTextPlugin.extract({ use: [ { loader: 'css-loader' }, { loader: 'sass-loader' } ], fallback:'style-loader' }) } plugins: [ new extractTextPlugin("css/index.css") ]
自动添加CSS属性前缀
npm i -D postcss-loader autoprefixer
需要再项目的根目录新建
postcss.config.js配置文件。
//postcss.config.js module.exports = { plugins: [ require('autoprefixer') ] }
//webpack.config.js { test: /\.css$/, use: extractTextPlugin.extract({ fallback: "style-loader", use: [ { loader: 'css-loader' }, { loader: 'postcss-loader' } //here ] }) }
更多的配置参考 postcss-loader
分离多余的CSS样式
有些时候css样式有多余的情况,比如使用 Bootstrap 这个库文件一小部分样式,或者项目几次改版产生了很多无效的CSS样式,这种情况下需要去除掉多余的CSS样式,以节省带宽。安装webpack插件 :
npm i -D purifycss-webpack purify-css
配置选项:
//webpack.config.js const glob = require('glob'); const purifyCssPlugin = require('purifycss-webpack') const extractTextPlugin = require('extract-text-webpack-plugin') plugin:[ ..., new purifyCssPlugin({ paths:glob.sync(path.join(__dirname,'src/*.html')) }) ]
这样就实现了多余代码的去除,好像是需要结合 CSS分离(
extract-text-webpack-plugin)技术,才能实现代码的去除。自己测试过程:把CSS分离去除后,也就是让CSS代码打包进
bundle.js文件里面,配置好代码,打包后没有去除掉多余的CSS文件,在
bundle.js文件里面还能找到样式。
使用Babel转换ES6和ES7语法
首先需要安装插件,我是结合 React 项目来使用 ES6 ES7 的,所以需要安装babel-preset-react来解析 React 的
jsx语法。
npm i -D babel-core babel-loader babel-preset-env babel-preset-react
//webpack.config.js { test: /\.(js|jsx)$/, use: [ { loader: 'babel-loader' , //options:{ 这里注意实际中不会这样配置,一般新建.babelrc文件来写这些配置项 // presets:["env","react"] //} } ], exclude: /node_modules/ //不需要转换node_modules下的js文件 }
实际开发中 babel 的配置代码会越来越多,不建议在
use中写 babel 的配置选项,而是在项目的根目录新建
.babelrc配置文件。
//.babelrc { "presets": ["react","env"] //渲染器 }
打包后的代码调试
打包有四种模式:source-map: 打包速度最慢,最详细,生成了一个
.map的独立的文件,放在
dist打包目录下,可以与打包后的文件很好的结合,报错信息包括 行 和 列。
cheap-module-source-map: 也生成独立文件,报错信息包括 行 和 不包括列,比上面的模式快。
eval-source-map: 不生成独立文件,报错信息包括 行 和 列,直接在
bundle.js文件中生成
map, 速度也很快,有安全和性能的隐患,只能在开发阶段使用,上线前一定要删除
devtool:'eval-source-map'。
cheap-module-eval-source-map:不生成独立文件, 报错信息包括 行 和 不包括列列,
//webpack.config.js module.exports = { devtool:'source-map', //here entry: {}, output: {}, module: {}, plugins: [], devServer: {} }
参考教程
相关文章推荐
- Webpack 3.0 的学习笔记(3)
- webpack之基础学习
- Webpack 基础学习
- js学习笔记:webpack基础入门(一)
- webpack学习笔记(一)从零开始构建基础webpack项目
- webpack学习(二):先写几个webpack基础demo
- js学习笔记:webpack基础入门(一)
- node+webpack环境搭建 vue.js 2.0 基础学习笔记
- JavaWeb学习笔记-Web基础-02
- webpack学习笔记
- webpack前端构建工具学习总结(二)之loader的使用
- webpack学习文档
- webpack学习笔记(二)环境分离+多页面开发配置
- webpack学习之入门实例
- 通过vue-cli来学习修改Webpack多环境配置和发布问题
- Webpack学习笔记 - 体验篇
- Webpack学习笔记
- 【Webpack 学习】2.四个核心概念及使用
- 女孩子零基础学习web前端开发怎么…
- 【Webpack 学习】3.多入口设置与 html-webpack-pugin 插件详解