![](/img/trans.png)
[英]Webpack dev-server - how to serve a static file with updated assets?
[英]Django/Webpack - How to serve generated webpack bundles with webpack dev server
Django 的 'static' 标签使用 STATIC_URL 生成 url,这会导致类似 '/static/myapp/js/bundle.js' 的结果同时,webpack-dev-server 正在提供来自 url 'localhost:3000' 的包
我的问题是如何让 Django 'static' 模板标签为 js 包生成不同的 url(指向 webpack 开发服务器)。 当然,我可以在模板中对其进行硬编码,但这不是一个好的解决方案。
下面是我的项目配置
webpack.config.js
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const BundleTracker = require('webpack-bundle-tracker')
module.exports = {
mode: 'development',
context: path.dirname(path.resolve(__dirname)),
entry: {
index: './typescript_src/index.ts',
},
output: {
path: path.resolve('./myproject/assets/myapp/bundles/'),
filename: "[name]-[hash].js"
},
resolve: {
extensions: ['.ts', '.js' ]
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
plugins: [
new CleanWebpackPlugin(),
new BundleTracker({filename: './myproject/webpack-stats.json'})
],
devServer: {
port: 3000,
publicPath: '/myapp/bundles/',
// hot: true,
headers: {
"Access-Control-Allow-Origin": "http://127.0.0.1:8000", /**Django dev server */
}
}
}
设置.py
WEBPACK_LOADER = {
'DEFAULT': {
'CACHE': not DEBUG,
'BUNDLE_DIR_NAME': 'myapp/bundles/', # must end with slash
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
'POLL_INTERVAL': 0.1,
'TIMEOUT': None,
'IGNORE': [r'.+\.hot-update.js', r'.+\.map']
}
}
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'assets'),
)
最初我决定 webpack 也应该在开发过程中提供其他静态文件
webpack.config.js
devServer: {
port: 3000,
publicPath: '/myapp/bundles/',
contentBase: path.resolve('./myproject/assets')
// hot: true,
headers: {
"Access-Control-Allow-Origin": "http://127.0.0.1:8000", /**Django dev server */
}
设置.py
# in development mode serve from wepack dev server
if DEBUG:
STATIC_URL = 'http://localhost:3000/'
else:
STATIC_URL = '/static/'
但后来我意识到我必须提供其他应用程序(admin、tinymce 等)的静态文件,这是 webpack Dev 服务器无法访问的
这里的问题是 django-webpack-loader (/static/myapp/bundles/bundle-name.js) 的 'render_bundle' 标签生成的 url 将导致 Http 404,因为 webpack-dev-server 将生成的包保留在内存而不是磁盘
另外如果我设置
STATIC_URL = localhost:3000
并配置 webpack-dev-server 为我的应用程序的其他静态文件提供服务,其他应用程序的静态文件将不会提供
我们来分析一下这个问题:
我们有 2 个服务器,我们希望根据请求的路径将请求路由到其中一个:
"/static/webpackbundles/** ==> webpack dev server
other paths ==> django dev server
这正是代理服务器的工作,它可以通过第三台服务器(haproxy、nginx ...)来实现,但这似乎webpack dev server
过头了,尤其是当我们知道webpack dev server
可以用作代理时! (https://webpack.js.org/configuration/dev-server/#devserverproxy )
webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'main.js',
path: '/path/to/django_project/django_project/static/webpackbundles',
publicPath: '/static/webpackbundles/',
},
devServer: {
contentBase: '/path/to/django_project/django_project/static/webpackbundles',
hot: true,
proxy: {
'!/static/webpackbundles/**': {
target: 'http://localhost:8000', // points to django dev server
changeOrigin: true,
},
},
},
};
在您的 Django 模板中:
<script type="text/javascript" src="{% static 'webpackbundles/main.js' %}"></script>
现在使用webpack dev server
地址访问您的 django 应用程序/站点:例如: http://localhost:8081
通过这个简单的配置,您将拥有浏览器自动刷新和热模块更换功能。 您不需要在 django 中更改任何内容,也不需要 django-webpack-loader
基于@Ejez 的回答,我能够配置 webpack-dev-server 来提供所有静态文件(包括媒体文件)
webpack.config.js
module.exports = {
// project root (usually package.json dir)
context: path.dirname(path.resolve(__dirname)),
output: {
path: path.resolve('./path/to/bundles/'),
filename: "[name]-[hash].js"
},
resolve: {
extensions: ['.ts', '.js' ]
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
plugins: [
new CleanWebpackPlugin(),
new BundleTracker({filename: '/path/to/webpack-stats.json'})
],
optimization: {
splitChunks: {
chunks: 'all',
name: 'lib' // bundle all their party libraries in lib.js
}
},
devServer: {
// if you do not mind webpack serving static files of other apps
// collect them (with django collectstatic) into /static_root/static/
// this way webpack-dev-server can serve from your own app's /static/
// directory and also /static_root/static/ directory (which contains
// static files of other apps
contentBase: [path.resolve('./project'), path.resolve('./project/static_root')],
// webpack bundles will be served from http://locahost:3000/static/project/bundles/
publicPath: '/static/project/bundles/',
port: 3000,
// proxy all request except (static and media files) to django dev server
proxy: [{
context: ['**', '!/static/**', '!/media/**'],
target: 'http://localhost:8000',
changeOrigin: true,
}]
}
}
现在您可以从 webpack-dev-server url localhost:3000
访问您的项目。 不要忘记启动两个开发服务器(webpack 和 django)
一般不合理使用STATICFILES_DIRS,而是使用STATIC_ROOT。 如果您有权将静态文件复制到项目文件夹,则使用 STATIC_ROOT。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.