webpack的使用及过程中遇到的问题和解决办法
写在前面的话:以下内容会结合实例进行分析webpack安装与使用过程中遇到的问题及解决方法
1、webpack安装
webpack可以使用npm进行安装,首先在任意磁盘下新建一个文件夹(我的建立在E盘)webpack-demo,请执行以下操作步骤:
(1)E: //转到E盘
(2)cd webpack-demo //转到webpack-demo文件夹
(3)npm init //通过这个命令可以自动创建一个package.json文件,这是一个标准的npm说明文件,里面包含当前项目的依赖模块,自定义的脚本任务等等
(4-1)npm install webpack -g //全局安装,或是
(4-2)npm install webpack --save-dev //本地安装
(5)在webpack-demo文件夹下新建app和dist两个文件夹,其中app文件夹用于存放原始数据和JS模块,dist文件夹存放之后供浏览器读取的文件,一般是index.html文件(包括使用webpack打包生成的js文件)
(6)在app文件夹下新建sayHello.js和main.js文件,在dist文件夹下新建index.html和main.js文件(由于webpack4之后在打包时会生成dist文件夹和main.js文件,因此这里需要创建,不然会报错)
2、不需任何配置使用webpack
webpack打包语法为:webpack {entry file} {output file},其中entry file代表入口文件的路径,也就是上面的app/main.js文件,output file代表打包后的文件存放路径,也就是上面的dist/main.js,然后执行以下命令:
(1-1)webpack app/main.js dist/main.js //全局安装webpack的使用此条命令
注意:经过本人实际测试发现,执行上述命令时会报错,根据实际的报错原因是需要安装webpack-cli,这是因为webpack4已将webpack命令行相关内容都迁移到了webpack-cli中,所以除了安装webpack之外还需要安装webpack-cli
(1-2)node_modules/.bin/webpack app/main.js dist/main.js //本地安装webpack的使用此条命令
(2)打开index.html文件即可查看输出内容
3、通过webpack.consig.js配置文件来使用webpack
正如上面第2步中看到的,当我们执行webpack打包命令时需要输入一长串的内容,这是非常不方便的,而且也很容易出错,那么怎么才能方便一点呢,就是通过webpack.config.js文件来实现,执行以下操作步骤:
(1)在webpack-demo文件夹下新建webpack.config.js文件并加入如下代码:
module.exports = {
entry: __dirname + "/app/main.js",//唯一的入口文件,其__dirname是当前执行脚本所在的目录
output: {
path: __dirname + "/dist",//打包后的文件存放路径
filename: "main.js"//打包后输出文件的文件名
}
}
(2-1)webpack //全局安装的执行这条命令,此命令会自动引用webpack.config.js文件中的配置选项
(2-2)node_modules/.bin/webpack //本地安装的执行这条命令
可以看出相比之前第2步(正式使用webpack)中的命令简单的很多
4、通过package.json文件使用webpack
正如上面第3步中看到的,我们在执行webpack打包命令时还是需要输入像webpack(或是node_modules/.bin/webpack)这样的命令,感觉还是很繁琐,怎么办呢,就是通过package.json实现,请执行以下操作步骤:
(1)在package.json文件中对scripts对象进行设置,代码如下:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack",
},
(2)npm start //package.json中的script会安装一定顺序寻找命令对应位置,本地的node_modules/.bin路径就在这个寻找清单中,所以无论是全局还是局部安装的webpack,你都不需要写前面那指明详细的路径了。
注意:在package.json文件的scripts对象中添加完"start":"webpack"之后执行npm start会报错误,也是类似上文已经提到的需要安装webbpack-cli,但是我们在上文报错时已经安装了webpack-cli,然而需要意识到我们在上文只是在全局安装了webpack-cli,而没有在本地安装,因此在这里需要进行本地安装webpack-cli,经过我实际测试,这样做之后就不会再报错了。但是,问题又来了,此时会有一个警告,大概意思是说'mode'没有定义,这是 webpack 4x 引入的,有两个值,development 和 production。默认是production。怎么解决呢?我们只需修改一下"start":"webpack"为"start":"webpack --config webpack.config.js --mode development"即可,其中--config webpack.config.js可以不写,默认就是它,此时再次运行npm start那命令行真的是干干净净,一个错误和警告都没有了!
5、webpack功能——Source Maps
我们在开发的过程中总是要调试代码,方便的调试能极大的提高开发效率,不过有时候通过打包后的文件,你是不容易找到出错了的地方,对应的你写的代码的位置的,Source Maps就是来帮我们解决这个问题的。通过简单的配置,webpack就可以在打包时为我们生成的source maps,这为我们提供了一种对应编译文件和源文件的方法,使得编译后的代码可读性更高,也更容易调试。在webpack的配置文件中配置source maps,需要配置devtool,它有以下四种不同的配置选项,各具优缺点,描述如下:
正如上表所述,上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对打包后的文件的的执行有一定影响。对小到中型的项目中,eval-source-map是一个很好的选项,再次强调你只应该开发阶段使用它,cheap-module-eval-source-map方法构建速度更快,但是不利于调试,推荐在大型项目考虑时间成本时使用。我们继续对上文新建的webpack.config.js,进行如下配置:
module.exports = {
devtool: 'eval-source-map',
}
6、webpack功能——构建本地服务器
我们在平时调试代码时总是修改之后要去刷新页面,那在webpack中我们可以通过构建本地服务器来实现自动刷新显示修改后的结果,webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建,可以实现你想要的这些功能,不过它是一个单独的组件,在webpack中进行配置之前需要单独安装它作为项目依赖,请执行以下操作步骤:
(1)npm install webpack-dev-server --save-dev
(2)devserver作为webpack配置选项中的一项,需要添加以下代码到webpack.config.js中
module.exports = {
devServer: {
contentBase: "./dist",//本地服务器所加载的页面所在的目录,要注意这里的./中的.千万不能丢失,否则启动服务器之后页面会输出Cannot GET /的错误
historyApiFallback: true,//在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html(即:不跳转)
inline: true,//设置为true,当源文件改变时会自动刷新页面
port: 8080//设置默认监听端口,如果省略,默认为"8080"
}
}
(3)添加以下命令到package.json文件中:
"scripts": {
"server": "webpack-dev-server --open --mode development"
}
(4)启动服务器:npm run server,启动之后会自动打开浏览器页面localhost:8080
注意:可能已经发现一些与上文不一样的东西了,什么呢?那就是为什么上文中我们配置完"start":"webpack"之后,我们在运行时输入的是npm start,而现在配置完"server":"..."之后运行的是npm run server,这其中多了一个run,这是因为npm的start命令是一个特殊的脚本名称,其特殊性表现在,在命令行中使用npm start就可以执行其对于的命令,如果对应的此脚本名称不是start,想要在命令行中运行时,需要这样用npm run {script name}如npm run server
7、webpack功能——loaders
Loaders是webpack提供的最激动人心的功能之一了。通过使用不同的loader,webpack有能力调用外部的脚本或工具,实现对不同格式的文件的处理,比如说分析转换scss为css,或者把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件,对React的开发而言,合适的Loaders可以把React的中用到的JSX文件转换为JS文件。Loaders需要单独安装并且需要在webpack.config.js中的modules关键字下进行配置。由于在编写程序的过程中我们会涉及到使用ES6、ES7、React等的情况,因此我在操作过程中会安装babel,其实babel是一个儿编译JavaScript的平台,它可以让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器完全支持;让你能使用基于JavaScript进行了拓展的语言,比如React的JSX。请执行以下操作步骤:
(1)安装babel:npm install babel-core babel-loader babel-preset-env babel-preset-react --save-dev //其中babel-core是核心功能,babel-preset-env用来解析ES6,babel-preset-react用来解析JSX语法,并且在一次性安装多个依赖模块时,模块之间用空格隔开
(2-1)配置babel:在webpack.config.js文件中加入以下代码:
module.exports = {
module: {
rules: [
{
test: /(\.jsx|\.js)$/,//一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)
use: {
loader: "babel-loader",//loader的名称(必须)
options: {
presets: [
"env", "react"
]
}
},
exclude: /node_modules/ //include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
}
]
}
}
(2-2)babel可以在webpack.config.js中进行配置,但是由于babel有很多配置项会导致webpack.config.js文件显得很臃肿,因此一般会把babel的配置项(options)单独放在一个名字为".babelrc"的配置文件中,配置完成后webpack会自动调用.babelrc文件里的babelrc配置选项
执行完上边步骤(2)之后我们就可以使用ES6和JSX语法来编写程序了,但是如果我们想使用React(JSX只是编写React的一种方式)编写程序还需要安装react和react-dom
(3)npm install react react-dom --save-dev
8、webpack功能——CSS
webpack中有两个处理样式表的工具:css-loader和style-loader,二者处理的任务不同,css-loader使你能够使用类似@import 和 url(...)的方法实现 require()的功能;style-loader将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。请执行以下操作步骤:
(1)npm install css-loader style-loader --save-dev
(2)在webpach.config.js中配置,代码如下:
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "style-loader"
}, {
loader: "css-loader"
}
]
}
]
}
}
9、webpack功能——CSS预处理器
Sass、Less之类的预处理器是对CSS的扩展,允许使用类似于变量的不存在与原生CSS中的特性来写CSS,CSS预处理器可以这些特殊类型的语句转化为浏览器可识别的CSS语句,其实存在一个CSS处理平台-PostCSS,帮助CSS实现更多的功能,请执行以下操作步骤:
(1)npm install postcss-loader autoprefixer --save-dev //autoprefixer是自动添加前缀的插件
(2)在webpack.config.js中添加postcss-loader,代码如下:
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "postcss-loader"
}
]
}
]
}
}
(3)在根目录新建postcss.config.js并添加如下代码:
module.exports = {
plugins: [
require('autoprefixer')
]
}
(4)npm start //你写的css会自动添加不同前缀了
10、webpack功能——插件(Plugins)
插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。与loaders的区别在于loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件(Plugins)并不直接操作单个文件,它直接对整个构建过程其作用。