为了账号安全,请及时绑定邮箱和手机立即绑定

请问webpack 服务器端必须用node 处理吗?

/ 猿问

请问webpack 服务器端必须用node 处理吗?

精慕HU 2019-07-17 15:11:17

webpack 服务器端必须用node 处理吗


查看完整描述

5 回答

?
慕容森

每个模块相关的 css、img、js 文件都放在一起,比较直观,删除模块时也会方便许多。测试文件也同样放在一起,哪些模块有没有写测试,哪些测试应该一起随模块删除,一目了然。
build
|-- webpack.config.js # 公共配置
|-- webpack.dev.js # 开发配置
|-- webpack.release.js # 发布配置
docs # 项目文档
node_modules
src # 项目源码
|-- conf # 配置文件
|-- pages # 页面目录
| |-- page1
| | |-- index.js # 页面逻辑
| | |-- index.scss # 页面样式
| | |-- img # 页面图片
| | | |-- xx.png
| | |-- __tests__ # 测试文件
| | | |-- xx.js
| |-- app.html # 入口页
| |-- app.js # 入口JS
|-- components # 组件目录
| |-- loading
| | |-- index.js
| | |-- index.scss
| | |-- __tests__
| | | |-- xx.js
|-- js
| |-- actions
| | |-- index.js
| | |-- __tests__
| | | |-- xx.js
| |-- reducers
| | |-- index.js
| | |-- __tests__
| | | |-- xx.js
| |-- xx.js
|-- css # 公共CSS目录
| |-- common.scss
|-- img # 公共图片目录
| |-- xx.png
tests # 其他测试文件
package.json
READNE.md

要完成的功能

编译 jsx、es6、scss 等资源

自动引入静态资源到相应 html 页面

实时编译和刷新浏览器

按指定模块化规范自动包装模块

自动给 css 添加浏览器内核前缀

按需打包合并 js、css

压缩 js、css、html

图片路径处理、压缩、CssSprite

对文件使用 hash 命名,做强缓存

语法检查

全局替换指定字符串

本地接口模拟服务

发布到远端机

针对以上的几点功能,接下来将一步一步的来完成这个
boilerplate 项目, 并记录下每一步的要点。

准备工作

1、根据前面的项目结构规划创建项目骨架
$ make dir webpack-react-redux-es6-boilerplate
$ cd webpack-react-redux-es6-boilerplate
$ mkdir build docs src mock tests
$ touch build/webpack.config.js build/webpack.dev.js build/webpack.release.js
// 创建 package.json
$ npm init
$ ...

2、安装最基本的几个 npm 包
$ npm i webpack webpack-dev-server --save-dev
$ npm i react react-dom react-router redux react-redux redux-thunk --save

3、编写示例代码,最终代码直接查看
boilerplate

4、根据
webpack 文档编写最基本的 webpack 配置,直接使用 NODE API 的方式
/* webpack.config.js */

var webpack = require('webpack');

// 辅助函数
var utils = require('./utils');
var fullPath = utils.fullPath;
var pickFiles = utils.pickFiles;

// 项目根路径
var ROOT_PATH = fullPath('../');
// 项目源码路径
var SRC_PATH = ROOT_PATH + '/src';
// 产出路径
var DIST_PATH = ROOT_PATH + '/dist';

// 是否是开发环境
var __DEV__ = process.env.NODE_ENV !== 'production';

// conf
var alias = pickFiles({
id: /(conf\/[^\/]+).js$/,
pattern: SRC_PATH + '/conf/*.js'
});

// components
alias = Object.assign(alias, pickFiles({
id: /(components\/[^\/]+)/,
pattern: SRC_PATH + '/components/*/index.js'
}));

// reducers
alias = Object.assign(alias, pickFiles({
id: /(reducers\/[^\/]+).js/,
pattern: SRC_PATH + '/js/reducers/*'
}));

// actions
alias = Object.assign(alias, pickFiles({
id: /(actions\/[^\/]+).js/,
pattern: SRC_PATH + '/js/actions/*'
}));

var config = {
context: SRC_PATH,
entry: {
app: ['./pages/app.js']
},
output: {
path: DIST_PATH,
filename: 'js/bundle.js'
},
module: {},
resolve: {
alias: alias
},
plugins: [
new webpack.DefinePlugin({
// http://stackoverflow.com/questions/30030031/passing-environment-dependent-variables-in-webpack
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || 'development')
})
]
};

module.exports = config;
/* webpack.dev.js */

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
var utils = require('./utils');

var PORT = 8080;
var HOST = utils.getIP();
var args = process.argv;
var hot = args.indexOf('--hot') > -1;
var deploy = args.indexOf('--deploy') > -1;

// 本地环境静态资源路径
var localPublicPath = 'http://' + HOST + ':' + PORT + '/';

config.output.publicPath = localPublicPath;
config.entry.app.unshift('webpack-dev-server/client?' + localPublicPath);

new WebpackDevServer(webpack(config), {
hot: hot,
inline: true,
compress: true,
stats: {
chunks: false,
children: false,
colors: true
},
// Set this as true if you want to access dev server from arbitrary url.
// This is handy if you are using a html5 router.
historyApiFallback: true,
}).listen(PORT, HOST, function() {
console.log(localPublicPath);
});

上面的配置写好后就可以开始构建了
$ node build/webpack.dev.js

因为项目中使用了 jsx、es6、scss,所以还要添加相应的 loader,否则会报如下类似错误:
ERROR in ./src/pages/app.js
Module parse failed: /Users/xiaoyan/working/webpack-react-redux-es6-boilerplate/src/pages/app.js Unexpected token (18:6)
You may need an appropriate loader to handle this file type.

编译 jsx、es6、scss 等资源

使用 bael 和
babel-loader 编译 jsx、es6

安装插件:
babel-preset-es2015 用于解析 es6

安装插件:babel-preset-react 用于解析
jsx

// 首先需要安装 babel
$ npm i babel-core --save-dev
// 安装插件
$ npm i babel-preset-es2015 babel-preset-react --save-dev
// 安装 loader
$ npm i babel-loader --save-dev

在项目根目录创建 .babelrc 文件:
{
"presets": ["es2015", "react"]
}

在 webpack.config.js 里添加:
// 使用缓存
var CACHE_PATH = ROOT_PATH + '/cache';
// loaders
config.module.loaders = [];
// 使用 babel 编译 jsx、es6
config.module.loaders.push({
test: /\.js$/,
exclude: /node_modules/,
include: SRC_PATH,
// 这里使用 loaders ,因为后面还需要添加 loader
loaders: ['babel?cacheDirectory=' + CACHE_PATH]
});


查看完整回答
反对 回复 2019-07-28
?
撒科打诨

node.js实现web服务器还是比较简单的,我了解node.js是从《node入门》开始的,如果你不了解node.js也可以看看!
我根据那书一步一步的练习完了,也的确大概了解了node.js,不过里面写的路由的地方总感觉不方便,十一放假最后一天,试着写了个简单的web服务器,现在分享记录于此!
http模块已提供了基本功能,所以我主要解决两个问题,1是静态资源的处理,2是动态资源的路由。
静态资源在node.js里的意思是不变的,如图片、前端js、css、html页面等。
动态资源我们一般指aspx页面,ashx页面,asp页面,jsp页面,php页面等,而node.js里其实没动态资源这一说,它对请求的处理都是由回调方法完成的,在我实现的httserver里,借鉴了ashx的写法,把处理请求的js文件看作动态资源。
首先实现一个处理静态资源的函数,其实就是对本地文件的读取操作,这个方法已满足了上面说的静态资源的处理。
//处理静态资源
function staticResHandler(localPath, ext, response) {
fs.readFile(localPath, "binary", function (error, file) {
if (error) {
response.writeHead(500, { "Content-Type": "text/plain" });
response.end("Server Error:" + error);
} else {
response.writeHead(200, { "Content-Type": getContentTypeByExt(ext) });
response.end(file, "binary");
}
});
}

而动态资源肯定不能一个方法搞定,就像你的网站有register.aspx、login.aspx等等,都需要你自己来写,在我的httpserver里,每个处理请求的js模块都导出processRequest(request,response)即可,比如实现一个register.js(只输出字符串register)
exports.processRequest = function (request, response) {
response.writeHead(200, { 'Content-Type': 'text/plain' });
resp.end("register");
}

现在当请求到来时,我们要做的就是决定怎么处理,即路由。
因为静态资源url指定静态资源大家都很习惯了,所以这里不变,比如
访问http://localhost/img/logo.png 就是访问 web根目录\img\logo.png;
访问http://localhost/js/what.js 就是访问 web根目录\js\what.js;
而动态资源也是一般的js文件,即服务器端js,就比如我实现的这个httpserver.js和上面说的register.js都是不应该让用户访问的,所以路由的时候要判断,就是一些if、else,简单而强大是我的最爱,这里只看最后的的判断,
fs.exists(localPath, function (exists) {
if (exists) {
if (staticRes) {
staticResHandler(localPath, ext, response); //静态资源

查看完整回答
反对 回复 2019-07-28
?
吃鸡游戏

使用webpack跟后台是否用nodejs无关,因为webpack在执行打包压缩的时候是依赖nodejs的,没有nodejs就不能使用webpack,就好比要使用电灯,首先必须得有电流,而电流是需要发动机来发电的。

查看完整回答
反对 回复 2019-07-28
?
qq_笑_17

Redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll、kqueue和select,对于单纯只有IO操作来说,单线程可以将速度优势发挥到最大,但是Redis也提供了一些简单的计算功能
比如排序、聚合等,对于这些操作,单线程模型实际会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞住的。

查看完整回答
反对 回复 2019-07-28
?
陪伴而非守候

去除不必要的插件
刚开始用 webpack 的时候,开发环境和生产环境用的是同一个 webpack 配置文件,导致生产环境打包的 JS 文件包含了一大堆没必要的插件,比如 HotModuleReplacementPlugin, NoErrorsPlugin... 这时候不管用什么优化方式,都没多大效果。所以,如果你打包后的文件非常大的话,先检查下是不是包含了这些插件。
提取第三方库
像 react 这个库的核心代码就有 627 KB,这样和我们的源代码放在一起打包,体积肯定会很大。所以可以在 webpack 中设置
{
entry: {
bundle: 'app'
vendor: ['react']
}
plugins: {
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js')
}
}

查看完整回答
反对 回复 2019-07-28

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信