如果已经将 webpack 安装到全局中,则可以直接使用 webpack 命令;如果非全局安装需使用,使用项目内部的 webpack 命令的话,需要使用如下方式来运行 webpack 命令:
node_modules/.bin/webpack
值得注意的是,npm start 命令可以引导任务执行,自动使用项目内部的 webpack 等命令。
注:package.json中的script会安装一定顺序寻找命令对应位置,本地的node_modules/.bin路径就在这个寻找清单中,所以无论是全局还是局部安装的Webpack,你都不需要写前面那指明详细的路径了。
使用webpack-dev-server中遇到不能浏览器无法自动刷新的问题;寻找多方答案后明白了一些;
下面有一些需要注意的点:
1.webpack-dev-server并不能读取你的webpack.config.js的配置output!!
你在webpack.config.js里面的配置output属性是你用webpack打包时候才起作用的,对webpack-dev-server并不起作用
2.webpack-dev-server打包生产的文件并不会添加在你的项目目录中!!它默认打包的文件名是bundle.js,不会真的出现在你的项目目录中。
注意:你启动webpack-dev-server后,你在目标文件夹中是看不到编译后的文件的,实时编译后的文件都保存到了内存当中。因此很多同学使用webpack-dev-server进行开发的时候都看不到编译后的文件
webpack-dev-server支持两种模式来自动刷新页面.
- iframe模式(页面放在iframe中,当发生改变时重载)
- inline模式(将webpack-dev-sever的客户端入口添加到包(bundle)中)
两种模式都支持热模块替换(Hot Module Replacement).热模块替换的好处是只替换更新的部分,而不是页面重载.
iframe模式
使用这种模式不需要额外的配置,只需要以下面这种URL格式访问即可
http://«host»:«port»/webpack-dev-server/«path»
例如:http://localhost:8080/webpack-dev-server/index.html
inline模式
1 当以命令行启动webpack-dev-server时,需要做两点:
在命令行中添加–inline命令
在webpack.config.js中添加devServer:{inline:true}//这个也可以不用。
2 当以Node.js API启动webpack-dev-server时,我们也需要做两点:
由于webpack-dev-server的配置中无inline选项,我们需要添加webpack-dev-server/client?http://«path»:«port»/到webpack配置的entry入口点中.
将<script src=“http://localhost:8080/webpack-dev-server.js”></script>添加到html文件中
var config = require("./webpack.config.js");
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, {
contentBase:'build/',
publicPath: "/assets/"
});
server.listen(8080);
示例:
自动刷新的配置方法(inline模式):
我习惯的做法是在项目的package.json里面添加
如下代码亲测有效:
项目结构图:
webpack.config.js
/**
* Created by DreamCatcher on 2017/11/1.
* 如果没有这个配置文件,需要使用如下命令手动打包:node_modules\.bin\webpack js\requireAddDiv1.js dist\bundle.js
* 如果有这个配置文件,只需要使用如下命令就可以了:node_modules\.bin\webpack
*/
var webpack = require("webpack");
module.exports = {
devtool: "eval-source-map",//生成Source Maps
//entry: "./js/requireAddDiv1.js",
entry: {
app: [
"./js/requireAddDiv1.js",
"webpack-dev-server/client?http://localhost:8080/" //只要这一个配置就可以实现CSS自动刷新。
]
},
output: {
path: __dirname + "/dist",
filename: "bundle.js"
},
module: {
/*在webpack2.0版本已经将 module.loaders 改为 module.rules 为了兼容性考虑以前的声明方法任然可用,
同时链式loader(用!连接)只适用于module.loader,
同时-loader不可省略
*/
/*loaders: [
{
test: "/(\.jsx|\.js)$/",
loader: "babel-loader"
},
{
//test: /\.\/css\/*\.css$/,//这种方式精确定位
test: "/\.css$/",
loader: "style-loader!css-loader"//这种方式只有 loaders 可以使用 rules 不可以
}
]*/
//以下是使用 rules 的方式:
rules: [
{
test: "/(\.jsx|\.js)$/",
use: {
loader: "babel-loader"
},
exclude: /node-modules/ //注意这里没有使用引号
},
{
test: "/\.css$/",
use: [ //引入多个loader的方法
"style-loader",
{
loader: "css-loader",
options: {
// modules: true // 设置css模块化,详情参考https://github.com/css-modules/css-modules
}
},
/*{
loader: 'postcss-loader',
// 在这里进行配置,也可以在postcss.config.js中进行配置,详情参考https://github.com/postcss/postcss-loader
options: {
plugins: function () {
return [
require('autoprefixer')
];
}
}
}*/
]
}
]
},
plugins: [
new webpack.BannerPlugin('版权所有,盗版必究!')
]
};
注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
webpack提供两个工具处理样式表,css-loader 和 style-loader,二者处理的任务不同,css-loader使你能够使用类似@import 和 url(…)的方法实现 require()的功能,style-loader将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。
如果需要使用到 postcss-loader, 需要首先安装postcss-loader 和 autoprefixer(自动添加前缀的插件)
npm install --save-dev postcss-loader autoprefixer
或是在 package.json 文件中进行配置。
devtool选项 | 配置结果 |
---|---|
source-map | 在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度; |
cheap-module-source-map | 在一个单独的文件中生成一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便; |
eval-source-map | 使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定不要启用这个选项; |
cheap-module-eval-source-map | 这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点; |
上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对打包后的文件的的执行有一定影响。对小到中型的项目中,eval-source-map是一个很好的选项,再次强调你只应该开发阶段使用它。
Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less…),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。
package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "My test of webpack",
"main": "js/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --inline --content-base"
},
"keywords": [
"webpack",
"test"
],
"author": "slHuang",
"license": "ISC",
"devDependencies": {
"webpack": "3.8.1",
"css-loader": "^0.28.7",
"style-loader": "^0.19.0",
"webpack-dev-server": "^2.9.3"
}
}
这样通过npm start命令就能启动 inline模式了,当然也可以具体的输入webpack-dev-server命令
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test webpack</title>
</head>
<body>
<h3>This is my first test.</h3>
<script src="bundle.js"></script>
</body>
</html>
关键的是你的index.html也就是你的项目入口的html文件里面引用这个bundle.js文件需要直接引用根目录下面的!一定不能写 webpack.config.js 中 output 中配置的路径,比如:dist/bundle.js
不能引用你webpack配置的bundle.js文件目录,webpack配置的这个bundle.js文件,只有在你手动打包webpack之后才会改变!
requireAddDiv1.js
/**
* Created by DreamCatcher on 2017/11/1.
*/
require("!style-loader!css-loader!../css/index.css");
var div = document.createElement("div");
div.innerHTML = "Added second div.";
document.body.appendChild(div);
var div2 = document.createElement("div");
div2.innerHTML = "Added second div2.";
document.body.appendChild(div2);
index.css
body {
background-color: yellow;
color: blue;
}
通过 npm start 启动项目,chrome 里面输入以下路径:http://localhost:8080/
页面就可以打开了。
然后,就是见证奇迹的时候了:
随便修改 index.css 中的一个属性,比如将 color 改成 red
这个时候,编译器就会自动编译:
这时候 chrome 中页面就会自动刷新,并且当前修改的属性,在页面上正常表现出来了,文字颜色变成了 red。
总结下就是:webpack里面配置的bundle.js需要手动打包才会变化目录可以由你自己指定!webpack-dev-server自动检测变化自动打包的是开发环境下的bundle.js,打包路径由你的contentBase决定!两个文件是不一样的
另外,停止 webpack-dev-server ,只需要在命令窗口中 ctrl + c 就可以了。
后面,还试了另一种配置:
接上面的示例,需要做如下修改:
1、将 webpack.config.js 添加如下配置:
module.exports = {
...
devServer: {
contentBase: "./",//本地服务器所加载的页面所在的目录
historyApiFallback: true,//不跳转
inline: true,//实时刷新
hot: true//hot module replacement. Depends on HotModuleReplacementPlugin
}
...
plugins: {
...
new webpack.HotModuleReplacementPlugin()
...
}
}
2、在package.json中的scripts对象中添加如下命令,用以开启本地服务器:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack",
"server": "webpack-dev-server --open" //这里的 open 是指运行 server 后自动打开 index.html页面
},
启动 server:
npm run server
这样也可以了。