I'm building a Django app that serves a single page Angular app.
我正在构建一个Django应用程序,它提供单页Angular应用程序。
Django serve's Angular's index.html which has the following usemin script block:
Django发布的Angular的index.html具有以下usemin脚本块:
<!-- build:js scripts/scripts.js -->
<script src="{% static "scripts/app.js" %}"></script>
<script src="{% static "scripts/controllers/main.js" %}"></script>
<script src="{% static "scripts/controllers/stats.js" %}"></script>
<script src="{% static "scripts/directives/highchart.js" %}"></script>
<!-- endbuild -->
Usemin tries to find "{% static "scripts/app.js" %}" on the filesystem and of course fails because what it should really be trying to find is "scripts/app.js".
Usemin尝试在文件系统上找到“{%static”scripts / app.js“%}”,当然失败了,因为它应该真正想要找到的是“scripts / app.js”。
Has anyone seen a workaround for this?
有没有人见过这个解决方法?
2 个解决方案
#1
9
Alright, I think I have a workaround. This is assuming you want the built file to also point to the static url for the built assets.
好吧,我想我有一个解决方法。这假设您希望构建的文件也指向构建资产的静态URL。
This will require you to define a STATIC_URL on your view context (instead of using src="{% static 'foo/bar.js' %}"
you'll use src="{{STATIC_URL}}foo/bar.js"
). I couldn't get {% static %}
to work without hacking the grunt-usemin source.
这将要求您在视图上下文中定义STATIC_URL(而不是使用src =“{%static'foo / bar.js'%}”您将使用src =“{{STATIC_URL}} foo / bar.js” )。如果不破解grunt-usemin源代码,我无法使{%static%}工作。
So using your example, this:
所以使用你的例子,这个:
<!-- build:js {{STATIC_URL}}scripts/scripts.js -->
<script src="{{STATIC_URL}}scripts/app.js"></script>
<script src="{{STATIC_URL}}scripts/controllers/main.js"></script>
<script src="{{STATIC_URL}}scripts/controllers/stats.js"></script>
<script src="{{STATIC_URL}}scripts/directives/highchart.js"></script>
<!-- endbuild -->
Compiles down to:
编译为:
<script src="{{STATIC_URL}}scripts/scripts.js"></script>
In order to achieve this, I had to add the following grunt configurations (in Gruntfile.js):
为了实现这一点,我不得不添加以下grunt配置(在Gruntfile.js中):
// custom createConfig script for replacing Django {{STATIC_URL}} references
// when building config for concat and cssmin
var path = require('path');
function createDjangoStaticConcatConfig(context, block) {
var cfg = {files: []};
var staticPattern = /\{\{\s*STATIC_URL\s*\}\}/;
block.dest = block.dest.replace(staticPattern, '');
var outfile = path.join(context.outDir, block.dest);
// Depending whether or not we're the last of the step we're not going to output the same thing
var files = {
dest: outfile,
src: []
};
context.inFiles.forEach(function(f) {
files.src.push(path.join(context.inDir, f.replace(staticPattern, '')));
});
cfg.files.push(files);
context.outFiles = [block.dest];
return cfg;
}
grunt.initConfig({
/*...*/
// add a preprocessor to modify the concat config to parse out {{STATIC_URL}} using the above method
useminPrepare: {
html: 'app/index.html',
options: {
dest: 'dist',
flow: {
steps: {
js: [
{
name: 'concat',
createConfig: createDjangoStaticConcatConfig
},
'uglifyjs'
],
// also apply it to css files
css: [
{
name: 'cssmin',
createConfig: createDjangoStaticConcatConfig
}
]
},
// this property is necessary
post: {}
}
}
},
// add a pattern to parse out the actual filename and remove the {{STATIC_URL}} bit
usemin: {
html: ['dist/{,*/}*.html'],
css: ['dist/styles/{,*/}*.css'],
options: {
assetsDirs: ['dist'],
patterns: {
html: [[/\{\{\s*STATIC_URL\s*\}\}([^'"]*)["']/mg, 'django static']]
}
}
},
// if you are using bower, also include the jsPattern to automatically
// insert {{STATIC_URL}} when inserting js files
'bower-install': {
app: {
html: 'app/index.html',
jsPattern: '<script type="text/javascript" src="{{STATIC_URL}}{{filePath}}"></script>'
}
}
});
#2
3
(I keept finding this question when googling for a solution, so I just share the solution i found here so that others like me can find it.)
(我在google搜索解决方案时发现这个问题,所以我只是分享我在这里找到的解决方案,以便像我这样的其他人可以找到它。)
I just discovered a grunt plugin called grunt-bridge that can wrap static files in a html template with the static
tag. The documentation is not great but I figured how to get it to work for my project.
我刚刚发现了一个名为grunt-bridge的grunt插件,它可以使用静态标记将静态文件包装在html模板中。文档不是很好,但我想到如何让它为我的项目工作。
If you have scripts like this:
如果您有这样的脚本:
<!-- build:js({.tmp,app}) /scripts/scripts.js -->
<script src="scripts/app.js"></script>
<script src="scripts/util/util.js"></script>
...
And the final output it to output something like this:
并最终输出它输出如下:
<script src="{% static 'adjangoappname/scripts/94223d51.scripts.js' %}"></script>
Install gruntbridge with npm install grunt-bridge --save-dev
and add a config like this in the grunt.initConfig of the Gruntfile.js:
使用npm install grunt-bridge --save-dev安装gruntbridge,并在Gruntfile.js的grunt.initConfig中添加如下配置:
bridge: {
distBaseHtml: {
options: {
pattern: '{% static \'adjangoappname{path}\' %}',
html: '<%= yeoman.minifiedDir %>/index.html', dest: '<%= yeoman.templateDir %>/index.html'
}
},
distIndexHtml: {
options: {
pattern: '{% static \'adjangoappname{path}\' %}',
html: '<%= yeoman.minifiedDir %>/index.html', dest: '<%= yeoman.templateDir %>/index.html'
}
},
// ... etc for each html file you want to modify
},
Where <%= yeoman.minifiedDir %>
is the output directory of the final minified html files, and <%= yeoman.minifiedDir %>
is the destination template directory. Replace adjangoappname
with the name of your django app or whatever directory prefix you want to have.
其中<%= yeoman.minifiedDir%>是最终缩小的html文件的输出目录,<%= yeoman.minifiedDir%>是目标模板目录。将adjangoappname替换为您的django应用程序的名称或您想要的任何目录前缀。
Then add grunt-bridge last in the registerTask list like this:
然后在registerTask列表中添加grunt-bridge,如下所示:
grunt.registerTask('build', [
//...
'htmlmin',
'bridge'
]);
(I think it's possible to make the config more compact, but this is the first method I discovered that worked)
(我认为可以使配置更紧凑,但这是我发现的第一种工作方法)
#1
9
Alright, I think I have a workaround. This is assuming you want the built file to also point to the static url for the built assets.
好吧,我想我有一个解决方法。这假设您希望构建的文件也指向构建资产的静态URL。
This will require you to define a STATIC_URL on your view context (instead of using src="{% static 'foo/bar.js' %}"
you'll use src="{{STATIC_URL}}foo/bar.js"
). I couldn't get {% static %}
to work without hacking the grunt-usemin source.
这将要求您在视图上下文中定义STATIC_URL(而不是使用src =“{%static'foo / bar.js'%}”您将使用src =“{{STATIC_URL}} foo / bar.js” )。如果不破解grunt-usemin源代码,我无法使{%static%}工作。
So using your example, this:
所以使用你的例子,这个:
<!-- build:js {{STATIC_URL}}scripts/scripts.js -->
<script src="{{STATIC_URL}}scripts/app.js"></script>
<script src="{{STATIC_URL}}scripts/controllers/main.js"></script>
<script src="{{STATIC_URL}}scripts/controllers/stats.js"></script>
<script src="{{STATIC_URL}}scripts/directives/highchart.js"></script>
<!-- endbuild -->
Compiles down to:
编译为:
<script src="{{STATIC_URL}}scripts/scripts.js"></script>
In order to achieve this, I had to add the following grunt configurations (in Gruntfile.js):
为了实现这一点,我不得不添加以下grunt配置(在Gruntfile.js中):
// custom createConfig script for replacing Django {{STATIC_URL}} references
// when building config for concat and cssmin
var path = require('path');
function createDjangoStaticConcatConfig(context, block) {
var cfg = {files: []};
var staticPattern = /\{\{\s*STATIC_URL\s*\}\}/;
block.dest = block.dest.replace(staticPattern, '');
var outfile = path.join(context.outDir, block.dest);
// Depending whether or not we're the last of the step we're not going to output the same thing
var files = {
dest: outfile,
src: []
};
context.inFiles.forEach(function(f) {
files.src.push(path.join(context.inDir, f.replace(staticPattern, '')));
});
cfg.files.push(files);
context.outFiles = [block.dest];
return cfg;
}
grunt.initConfig({
/*...*/
// add a preprocessor to modify the concat config to parse out {{STATIC_URL}} using the above method
useminPrepare: {
html: 'app/index.html',
options: {
dest: 'dist',
flow: {
steps: {
js: [
{
name: 'concat',
createConfig: createDjangoStaticConcatConfig
},
'uglifyjs'
],
// also apply it to css files
css: [
{
name: 'cssmin',
createConfig: createDjangoStaticConcatConfig
}
]
},
// this property is necessary
post: {}
}
}
},
// add a pattern to parse out the actual filename and remove the {{STATIC_URL}} bit
usemin: {
html: ['dist/{,*/}*.html'],
css: ['dist/styles/{,*/}*.css'],
options: {
assetsDirs: ['dist'],
patterns: {
html: [[/\{\{\s*STATIC_URL\s*\}\}([^'"]*)["']/mg, 'django static']]
}
}
},
// if you are using bower, also include the jsPattern to automatically
// insert {{STATIC_URL}} when inserting js files
'bower-install': {
app: {
html: 'app/index.html',
jsPattern: '<script type="text/javascript" src="{{STATIC_URL}}{{filePath}}"></script>'
}
}
});
#2
3
(I keept finding this question when googling for a solution, so I just share the solution i found here so that others like me can find it.)
(我在google搜索解决方案时发现这个问题,所以我只是分享我在这里找到的解决方案,以便像我这样的其他人可以找到它。)
I just discovered a grunt plugin called grunt-bridge that can wrap static files in a html template with the static
tag. The documentation is not great but I figured how to get it to work for my project.
我刚刚发现了一个名为grunt-bridge的grunt插件,它可以使用静态标记将静态文件包装在html模板中。文档不是很好,但我想到如何让它为我的项目工作。
If you have scripts like this:
如果您有这样的脚本:
<!-- build:js({.tmp,app}) /scripts/scripts.js -->
<script src="scripts/app.js"></script>
<script src="scripts/util/util.js"></script>
...
And the final output it to output something like this:
并最终输出它输出如下:
<script src="{% static 'adjangoappname/scripts/94223d51.scripts.js' %}"></script>
Install gruntbridge with npm install grunt-bridge --save-dev
and add a config like this in the grunt.initConfig of the Gruntfile.js:
使用npm install grunt-bridge --save-dev安装gruntbridge,并在Gruntfile.js的grunt.initConfig中添加如下配置:
bridge: {
distBaseHtml: {
options: {
pattern: '{% static \'adjangoappname{path}\' %}',
html: '<%= yeoman.minifiedDir %>/index.html', dest: '<%= yeoman.templateDir %>/index.html'
}
},
distIndexHtml: {
options: {
pattern: '{% static \'adjangoappname{path}\' %}',
html: '<%= yeoman.minifiedDir %>/index.html', dest: '<%= yeoman.templateDir %>/index.html'
}
},
// ... etc for each html file you want to modify
},
Where <%= yeoman.minifiedDir %>
is the output directory of the final minified html files, and <%= yeoman.minifiedDir %>
is the destination template directory. Replace adjangoappname
with the name of your django app or whatever directory prefix you want to have.
其中<%= yeoman.minifiedDir%>是最终缩小的html文件的输出目录,<%= yeoman.minifiedDir%>是目标模板目录。将adjangoappname替换为您的django应用程序的名称或您想要的任何目录前缀。
Then add grunt-bridge last in the registerTask list like this:
然后在registerTask列表中添加grunt-bridge,如下所示:
grunt.registerTask('build', [
//...
'htmlmin',
'bridge'
]);
(I think it's possible to make the config more compact, but this is the first method I discovered that worked)
(我认为可以使配置更紧凑,但这是我发现的第一种工作方法)