I am building an application which I would like to deploy as a CDF file, and I am struggling to make the CDF exports work correctly with functions pulled from a .m package file. What are good/best practices for handling such situations?
In particular, the code below encapsulates (at least partly) some of my difficulties. Make a package in the file TestPackage.m with the definitions
BeginPackage["TestPackage`"]
f::usage="f[x] returns a plot.";
Begin["`Private`"]
f[x_]:=Plot[Sin[x y],{y,0,2 Pi},PlotRange->{-1,1},ImageSize->500]
End[]
EndPackage[]
and include it in the same directory as the following code in a notebook.
Needs["TestPackage`", NotebookDirectory[] <> "TestPackage.m"]
DynamicModule[
{a = 1},
Column[{
Slider[Dynamic[a]],
Dynamic[f[a]]
}]
, Initialization :> (
Needs["TestPackage`", NotebookDirectory[] <> "TestPackage.m"]
)
]
Export[NotebookDirectory[] <> "output.cdf", EvaluationNotebook[]]
The DynamicModule correctly produces the desired output. If I close the notebook and reopen it, the plot renders correctly (which is not the case if the Initialization Needs is omitted). If I open the resulting output.cdf using Mathematica, the plot also renders correctly.
However, if I open output.cdf using the Wolfram CDF Player 10.1, the only thing that shows underneath the Slider is TestPackage`f[1.] (or whatever the value of a is).
I also tried naively spewing the contents of the package onto the initialization rule, along the lines of
Initialization :> (
ImportString[Import[NotebookDirectory[] <> "TestPackage.m", "Text"],
"NB"]
)
but it produces exactly the same behaviour. Presumably there exists a way to do this, but this simply puts the above code into the CDF, which the player then refuses to execute.
How can I make this plot render correctly in the exported CDF version?

SaveDefinitionsoption (just a guess. By far not an expert on this). – Leonid Shifrin Jun 23 '15 at 21:23Withyour package in text form toInitializationandGet+StringToStreamif you don't trustSaveDefinitions. You should be able to incorporate password protected encoded packages with this method. Not perfect but nice enough for free player. – Kuba Jun 23 '15 at 21:29SaveDefinitionsdoes in fact fix this example. Which means that this doesn't capture whatever is wrong with my bigger code. Back to the drawing board on that, then. Still, if there's a way to replicate the package's definitions in the Initialization stage it should help there. – Emilio Pisanty Jun 23 '15 at 21:42